Bug 1161859 - Compute the size of animated image frames correctly in the SurfaceCache. r=dholbert

This commit is contained in:
Seth Fowler 2015-05-05 22:19:30 -07:00
parent db496a806e
commit b699f89076
4 changed files with 20 additions and 7 deletions

View File

@ -473,7 +473,8 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
return RawAccessFrameRef();
}
if (!SurfaceCache::CanHold(aTargetSize)) {
const uint32_t bytesPerPixel = aPaletteDepth == 0 ? 4 : 1;
if (!SurfaceCache::CanHold(aFrameRect.Size(), bytesPerPixel)) {
NS_WARNING("Trying to add frame that's too large for the SurfaceCache");
return RawAccessFrameRef();
}

View File

@ -67,9 +67,10 @@ static StaticRefPtr<SurfaceCacheImpl> sInstance;
typedef size_t Cost;
static Cost
ComputeCost(const IntSize& aSize)
ComputeCost(const IntSize& aSize, uint32_t aBytesPerPixel)
{
return aSize.width * aSize.height * 4; // width * height * 4 bytes (32bpp)
MOZ_ASSERT(aBytesPerPixel == 1 || aBytesPerPixel == 4);
return aSize.width * aSize.height * aBytesPerPixel;
}
/**
@ -1003,18 +1004,18 @@ SurfaceCache::Insert(imgFrame* aSurface,
}
MutexAutoLock lock(sInstance->GetMutex());
Cost cost = ComputeCost(aSurfaceKey.Size());
Cost cost = ComputeCost(aSurface->GetSize(), aSurface->GetBytesPerPixel());
return sInstance->Insert(aSurface, cost, aImageKey, aSurfaceKey, aLifetime);
}
/* static */ bool
SurfaceCache::CanHold(const IntSize& aSize)
SurfaceCache::CanHold(const IntSize& aSize, uint32_t aBytesPerPixel /* = 4 */)
{
if (!sInstance) {
return false;
}
Cost cost = ComputeCost(aSize);
Cost cost = ComputeCost(aSize, aBytesPerPixel);
return sInstance->CanHold(cost);
}

View File

@ -288,10 +288,13 @@ struct SurfaceCache
* for sure the cache can't hold it.
*
* @param aSize The dimensions of a surface in pixels.
* @param aBytesPerPixel How many bytes each pixel of the surface requires.
* Defaults to 4, which is appropriate for RGBA or RGBX
* images.
*
* @return false if the surface cache can't hold a surface of that size.
*/
static bool CanHold(const IntSize& aSize);
static bool CanHold(const IntSize& aSize, uint32_t aBytesPerPixel = 4);
static bool CanHold(size_t aSize);
/**

View File

@ -236,6 +236,14 @@ public:
*/
void WaitUntilComplete() const;
/**
* Returns the number of bytes per pixel this imgFrame requires. This is a
* worst-case value that does not take into account the effects of format
* changes caused by Optimize(), since an imgFrame is not optimized throughout
* its lifetime.
*/
uint32_t GetBytesPerPixel() const { return GetIsPaletted() ? 1 : 4; }
IntSize GetImageSize() const { return mImageSize; }
nsIntRect GetRect() const;
IntSize GetSize() const { return mSize; }