зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1256603. Only mark images as used in the surface cache if we actually use them. r=aosmond
We were marking them used even if only a decode was requested. This can cause us to hold extra decoded copies of the image around because we have a tendency to request decode at the intrinsic size.
This commit is contained in:
Родитель
da38782e5c
Коммит
df61b9e8ff
|
@ -37,7 +37,8 @@ AnimationState::UpdateState(bool aAnimationFinished,
|
||||||
SurfaceCache::Lookup(ImageKey(aImage),
|
SurfaceCache::Lookup(ImageKey(aImage),
|
||||||
RasterSurfaceKey(aSize,
|
RasterSurfaceKey(aSize,
|
||||||
DefaultSurfaceFlags(),
|
DefaultSurfaceFlags(),
|
||||||
PlaybackType::eAnimated));
|
PlaybackType::eAnimated),
|
||||||
|
/* aMarkUsed = */ false);
|
||||||
|
|
||||||
return UpdateStateInternal(result, aAnimationFinished, aSize, aAllowInvalidation);
|
return UpdateStateInternal(result, aAnimationFinished, aSize, aAllowInvalidation);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +399,8 @@ FrameAnimator::ResetAnimation(AnimationState& aState)
|
||||||
SurfaceCache::Lookup(ImageKey(mImage),
|
SurfaceCache::Lookup(ImageKey(mImage),
|
||||||
RasterSurfaceKey(mSize,
|
RasterSurfaceKey(mSize,
|
||||||
DefaultSurfaceFlags(),
|
DefaultSurfaceFlags(),
|
||||||
PlaybackType::eAnimated));
|
PlaybackType::eAnimated),
|
||||||
|
/* aMarkUsed = */ false);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -427,7 +429,8 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
|
||||||
SurfaceCache::Lookup(ImageKey(mImage),
|
SurfaceCache::Lookup(ImageKey(mImage),
|
||||||
RasterSurfaceKey(mSize,
|
RasterSurfaceKey(mSize,
|
||||||
DefaultSurfaceFlags(),
|
DefaultSurfaceFlags(),
|
||||||
PlaybackType::eAnimated));
|
PlaybackType::eAnimated),
|
||||||
|
/* aMarkUsed = */ true);
|
||||||
|
|
||||||
ret.mDirtyRect = aState.UpdateStateInternal(result, aAnimationFinished, mSize);
|
ret.mDirtyRect = aState.UpdateStateInternal(result, aAnimationFinished, mSize);
|
||||||
if (aState.IsDiscarded() || !result) {
|
if (aState.IsDiscarded() || !result) {
|
||||||
|
@ -502,7 +505,7 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult
|
LookupResult
|
||||||
FrameAnimator::GetCompositedFrame(AnimationState& aState)
|
FrameAnimator::GetCompositedFrame(AnimationState& aState, bool aMarkUsed)
|
||||||
{
|
{
|
||||||
aState.mCompositedFrameRequested = true;
|
aState.mCompositedFrameRequested = true;
|
||||||
|
|
||||||
|
@ -517,7 +520,8 @@ FrameAnimator::GetCompositedFrame(AnimationState& aState)
|
||||||
SurfaceCache::Lookup(ImageKey(mImage),
|
SurfaceCache::Lookup(ImageKey(mImage),
|
||||||
RasterSurfaceKey(mSize,
|
RasterSurfaceKey(mSize,
|
||||||
DefaultSurfaceFlags(),
|
DefaultSurfaceFlags(),
|
||||||
PlaybackType::eAnimated));
|
PlaybackType::eAnimated),
|
||||||
|
aMarkUsed);
|
||||||
|
|
||||||
if (aState.mCompositedFrameInvalid) {
|
if (aState.mCompositedFrameInvalid) {
|
||||||
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
|
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
|
||||||
|
|
|
@ -323,7 +323,8 @@ public:
|
||||||
* not have required compositing). It may not be available because it hasn't
|
* not have required compositing). It may not be available because it hasn't
|
||||||
* been decoded yet, in which case we return an empty LookupResult.
|
* been decoded yet, in which case we return an empty LookupResult.
|
||||||
*/
|
*/
|
||||||
LookupResult GetCompositedFrame(AnimationState& aState);
|
LookupResult GetCompositedFrame(AnimationState& aState,
|
||||||
|
bool aMarkUsed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect an accounting of the memory occupied by the compositing surfaces we
|
* Collect an accounting of the memory occupied by the compositing surfaces we
|
||||||
|
|
|
@ -298,13 +298,14 @@ RasterImage::GetType(uint16_t* aType)
|
||||||
LookupResult
|
LookupResult
|
||||||
RasterImage::LookupFrameInternal(const IntSize& aSize,
|
RasterImage::LookupFrameInternal(const IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType)
|
PlaybackType aPlaybackType,
|
||||||
|
bool aMarkUsed)
|
||||||
{
|
{
|
||||||
if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
|
if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
|
||||||
MOZ_ASSERT(mFrameAnimator);
|
MOZ_ASSERT(mFrameAnimator);
|
||||||
MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
|
MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
|
||||||
"Can't composite frames with non-default surface flags");
|
"Can't composite frames with non-default surface flags");
|
||||||
return mFrameAnimator->GetCompositedFrame(*mAnimationState);
|
return mFrameAnimator->GetCompositedFrame(*mAnimationState, aMarkUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
|
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
|
||||||
|
@ -316,20 +317,23 @@ RasterImage::LookupFrameInternal(const IntSize& aSize,
|
||||||
return SurfaceCache::Lookup(ImageKey(this),
|
return SurfaceCache::Lookup(ImageKey(this),
|
||||||
RasterSurfaceKey(aSize,
|
RasterSurfaceKey(aSize,
|
||||||
surfaceFlags,
|
surfaceFlags,
|
||||||
PlaybackType::eStatic));
|
PlaybackType::eStatic),
|
||||||
|
aMarkUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll return the best match we can find to the requested frame.
|
// We'll return the best match we can find to the requested frame.
|
||||||
return SurfaceCache::LookupBestMatch(ImageKey(this),
|
return SurfaceCache::LookupBestMatch(ImageKey(this),
|
||||||
RasterSurfaceKey(aSize,
|
RasterSurfaceKey(aSize,
|
||||||
surfaceFlags,
|
surfaceFlags,
|
||||||
PlaybackType::eStatic));
|
PlaybackType::eStatic),
|
||||||
|
aMarkUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult
|
LookupResult
|
||||||
RasterImage::LookupFrame(const IntSize& aSize,
|
RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType)
|
PlaybackType aPlaybackType,
|
||||||
|
bool aMarkUsed /* = true */)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -347,7 +351,7 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult result =
|
LookupResult result =
|
||||||
LookupFrameInternal(requestedSize, aFlags, aPlaybackType);
|
LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed);
|
||||||
|
|
||||||
if (!result && !mHasSize) {
|
if (!result && !mHasSize) {
|
||||||
// We can't request a decode without knowing our intrinsic size. Give up.
|
// We can't request a decode without knowing our intrinsic size. Give up.
|
||||||
|
@ -377,7 +381,7 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
|
|
||||||
// If we can or did sync decode, we should already have the frame.
|
// If we can or did sync decode, we should already have the frame.
|
||||||
if (ranSync || (aFlags & FLAG_SYNC_DECODE)) {
|
if (ranSync || (aFlags & FLAG_SYNC_DECODE)) {
|
||||||
result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType);
|
result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +466,8 @@ RasterImage::WillDrawOpaqueNow()
|
||||||
SurfaceCache::LookupBestMatch(ImageKey(this),
|
SurfaceCache::LookupBestMatch(ImageKey(this),
|
||||||
RasterSurfaceKey(mSize,
|
RasterSurfaceKey(mSize,
|
||||||
DefaultSurfaceFlags(),
|
DefaultSurfaceFlags(),
|
||||||
PlaybackType::eStatic));
|
PlaybackType::eStatic),
|
||||||
|
/* aMarkUsed = */ false);
|
||||||
MatchType matchType = result.Type();
|
MatchType matchType = result.Type();
|
||||||
if (matchType == MatchType::NOT_FOUND || matchType == MatchType::PENDING ||
|
if (matchType == MatchType::NOT_FOUND || matchType == MatchType::PENDING ||
|
||||||
!result.Surface()->IsFinished()) {
|
!result.Surface()->IsFinished()) {
|
||||||
|
@ -1200,7 +1205,7 @@ RasterImage::RequestDecodeForSizeInternal(const IntSize& aSize, uint32_t aFlags)
|
||||||
// Perform a frame lookup, which will implicitly start decoding if needed.
|
// Perform a frame lookup, which will implicitly start decoding if needed.
|
||||||
PlaybackType playbackType = mAnimationState ? PlaybackType::eAnimated
|
PlaybackType playbackType = mAnimationState ? PlaybackType::eAnimated
|
||||||
: PlaybackType::eStatic;
|
: PlaybackType::eStatic;
|
||||||
LookupResult result = LookupFrame(aSize, flags, playbackType);
|
LookupResult result = LookupFrame(aSize, flags, playbackType, /* aMarkUsed = */ false);
|
||||||
return std::move(result.Surface());
|
return std::move(result.Surface());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,19 +284,22 @@ private:
|
||||||
* data, we'll attempt a sync decode if no matching surface is found. If
|
* data, we'll attempt a sync decode if no matching surface is found. If
|
||||||
* FLAG_SYNC_DECODE was not specified and no matching surface was found, we'll
|
* FLAG_SYNC_DECODE was not specified and no matching surface was found, we'll
|
||||||
* kick off an async decode so that the surface is (hopefully) available next
|
* kick off an async decode so that the surface is (hopefully) available next
|
||||||
* time it's requested.
|
* time it's requested. aMarkUsed determines if we mark the surface used in
|
||||||
|
* the surface cache or not.
|
||||||
*
|
*
|
||||||
* @return a drawable surface, which may be empty if the requested surface
|
* @return a drawable surface, which may be empty if the requested surface
|
||||||
* could not be found.
|
* could not be found.
|
||||||
*/
|
*/
|
||||||
LookupResult LookupFrame(const gfx::IntSize& aSize,
|
LookupResult LookupFrame(const gfx::IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType);
|
PlaybackType aPlaybackType,
|
||||||
|
bool aMarkUsed = true);
|
||||||
|
|
||||||
/// Helper method for LookupFrame().
|
/// Helper method for LookupFrame().
|
||||||
LookupResult LookupFrameInternal(const gfx::IntSize& aSize,
|
LookupResult LookupFrameInternal(const gfx::IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType);
|
PlaybackType aPlaybackType,
|
||||||
|
bool aMarkUsed);
|
||||||
|
|
||||||
ImgDrawResult DrawInternal(DrawableSurface&& aFrameRef,
|
ImgDrawResult DrawInternal(DrawableSurface&& aFrameRef,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
|
|
|
@ -999,7 +999,8 @@ public:
|
||||||
|
|
||||||
LookupResult LookupBestMatch(const ImageKey aImageKey,
|
LookupResult LookupBestMatch(const ImageKey aImageKey,
|
||||||
const SurfaceKey& aSurfaceKey,
|
const SurfaceKey& aSurfaceKey,
|
||||||
const StaticMutexAutoLock& aAutoLock)
|
const StaticMutexAutoLock& aAutoLock,
|
||||||
|
bool aMarkUsed /* = true */)
|
||||||
{
|
{
|
||||||
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
|
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
|
@ -1045,7 +1046,8 @@ public:
|
||||||
|
|
||||||
if (matchType == MatchType::EXACT ||
|
if (matchType == MatchType::EXACT ||
|
||||||
matchType == MatchType::SUBSTITUTE_BECAUSE_BEST) {
|
matchType == MatchType::SUBSTITUTE_BECAUSE_BEST) {
|
||||||
if (!MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock)) {
|
if (aMarkUsed &&
|
||||||
|
!MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock)) {
|
||||||
Remove(WrapNotNull(surface), /* aStopTracking */ false, aAutoLock);
|
Remove(WrapNotNull(surface), /* aStopTracking */ false, aAutoLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1518,8 @@ SurfaceCache::Shutdown()
|
||||||
|
|
||||||
/* static */ LookupResult
|
/* static */ LookupResult
|
||||||
SurfaceCache::Lookup(const ImageKey aImageKey,
|
SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||||
const SurfaceKey& aSurfaceKey)
|
const SurfaceKey& aSurfaceKey,
|
||||||
|
bool aMarkUsed /* = true */)
|
||||||
{
|
{
|
||||||
nsTArray<RefPtr<CachedSurface>> discard;
|
nsTArray<RefPtr<CachedSurface>> discard;
|
||||||
LookupResult rv(MatchType::NOT_FOUND);
|
LookupResult rv(MatchType::NOT_FOUND);
|
||||||
|
@ -1527,7 +1530,7 @@ SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = sInstance->Lookup(aImageKey, aSurfaceKey, lock);
|
rv = sInstance->Lookup(aImageKey, aSurfaceKey, lock, aMarkUsed);
|
||||||
sInstance->TakeDiscard(discard, lock);
|
sInstance->TakeDiscard(discard, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1536,7 +1539,8 @@ SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||||
|
|
||||||
/* static */ LookupResult
|
/* static */ LookupResult
|
||||||
SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
|
SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
|
||||||
const SurfaceKey& aSurfaceKey)
|
const SurfaceKey& aSurfaceKey,
|
||||||
|
bool aMarkUsed /* = true */)
|
||||||
{
|
{
|
||||||
nsTArray<RefPtr<CachedSurface>> discard;
|
nsTArray<RefPtr<CachedSurface>> discard;
|
||||||
LookupResult rv(MatchType::NOT_FOUND);
|
LookupResult rv(MatchType::NOT_FOUND);
|
||||||
|
@ -1547,7 +1551,7 @@ SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock);
|
rv = sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock, aMarkUsed);
|
||||||
sInstance->TakeDiscard(discard, lock);
|
sInstance->TakeDiscard(discard, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,8 @@ struct SurfaceCache
|
||||||
* if the cache entry was found.
|
* if the cache entry was found.
|
||||||
*/
|
*/
|
||||||
static LookupResult Lookup(const ImageKey aImageKey,
|
static LookupResult Lookup(const ImageKey aImageKey,
|
||||||
const SurfaceKey& aSurfaceKey);
|
const SurfaceKey& aSurfaceKey,
|
||||||
|
bool aMarkUsed = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the best matching cache entry and returns a drawable reference to
|
* Looks up the best matching cache entry and returns a drawable reference to
|
||||||
|
@ -251,7 +252,8 @@ struct SurfaceCache
|
||||||
* returned surface exactly matches @aSurfaceKey.
|
* returned surface exactly matches @aSurfaceKey.
|
||||||
*/
|
*/
|
||||||
static LookupResult LookupBestMatch(const ImageKey aImageKey,
|
static LookupResult LookupBestMatch(const ImageKey aImageKey,
|
||||||
const SurfaceKey& aSurfaceKey);
|
const SurfaceKey& aSurfaceKey,
|
||||||
|
bool aMarkUsed = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an ISurfaceProvider into the cache. If an entry with the same
|
* Insert an ISurfaceProvider into the cache. If an entry with the same
|
||||||
|
|
Загрузка…
Ссылка в новой задаче