Bug 786444 - Part 2 - Make imgFrame's lock status a count, not a boolean, so you can lock it multiple times and still be correct. r=jlebar

Also add a bunch of NS_ABORT_IF_FALSEs that verify that the lock status is
always valid.

--HG--
extra : rebase_source : 70cce5ed671586529e7d698e4bcdc86f5c748aa5
This commit is contained in:
Joe Drew 2012-09-26 11:33:06 -04:00
parent e917757e7c
commit 453116079c
2 changed files with 38 additions and 15 deletions

View File

@ -109,6 +109,7 @@ imgFrame::imgFrame() :
mSinglePixelColor(0),
mTimeout(100),
mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */
mLockCount(0),
mBlendMethod(1), /* imgIContainer::kBlendOver */
mSinglePixel(false),
mNeverUseDeviceSurface(false),
@ -118,7 +119,6 @@ imgFrame::imgFrame() :
#ifdef USE_WIN_SURFACE
mIsDDBSurface(false),
#endif
mLocked(false),
mInformedDiscardTracker(false)
{
static bool hasCheckedOptimize = false;
@ -578,6 +578,8 @@ uint32_t imgFrame::GetImageDataLength() const
void imgFrame::GetImageData(uint8_t **aData, uint32_t *length) const
{
NS_ABORT_IF_FALSE(mLockCount != 0, "Can't GetImageData unless frame is locked");
if (mImageSurface)
*aData = mImageSurface->Data();
else if (mPalettedImageData)
@ -600,6 +602,8 @@ bool imgFrame::GetHasAlpha() const
void imgFrame::GetPaletteData(uint32_t **aPalette, uint32_t *length) const
{
NS_ABORT_IF_FALSE(mLockCount != 0, "Can't GetPaletteData unless frame is locked");
if (!mPalettedImageData) {
*aPalette = nullptr;
*length = 0;
@ -611,14 +615,21 @@ void imgFrame::GetPaletteData(uint32_t **aPalette, uint32_t *length) const
nsresult imgFrame::LockImageData()
{
if (mPalettedImageData)
return NS_ERROR_NOT_AVAILABLE;
NS_ABORT_IF_FALSE(!mLocked, "Trying to lock already locked image data.");
if (mLocked) {
NS_ABORT_IF_FALSE(mLockCount >= 0, "Unbalanced locks and unlocks");
if (mLockCount < 0) {
return NS_ERROR_FAILURE;
}
mLocked = true;
mLockCount++;
// If we are not the first lock, there's nothing to do.
if (mLockCount != 1) {
return NS_OK;
}
// Paletted images don't have surfaces, so there's nothing to do.
if (mPalettedImageData)
return NS_OK;
if ((mOptSurface || mSinglePixel) && !mImageSurface) {
// Recover the pixels
@ -659,15 +670,26 @@ nsresult imgFrame::LockImageData()
nsresult imgFrame::UnlockImageData()
{
if (mPalettedImageData)
return NS_ERROR_NOT_AVAILABLE;
NS_ABORT_IF_FALSE(mLocked, "Unlocking an unlocked image!");
if (!mLocked) {
NS_ABORT_IF_FALSE(mLockCount != 0, "Unlocking an unlocked image!");
if (mLockCount == 0) {
return NS_ERROR_FAILURE;
}
mLocked = false;
mLockCount--;
NS_ABORT_IF_FALSE(mLockCount >= 0, "Unbalanced locks and unlocks");
if (mLockCount < 0) {
return NS_ERROR_FAILURE;
}
// If we are not the last lock, there's nothing to do.
if (mLockCount != 0) {
return NS_OK;
}
// Paletted images don't have surfaces, so there's nothing to do.
if (mPalettedImageData)
return NS_OK;
// Assume we've been written to.
if (mImageSurface)

View File

@ -157,6 +157,9 @@ private: // data
int32_t mTimeout; // -1 means display forever
int32_t mDisposalMethod;
/** Indicates how many readers currently have locked this frame */
int32_t mLockCount;
gfxASurface::gfxImageFormat mFormat;
uint8_t mPaletteDepth;
int8_t mBlendMethod;
@ -165,8 +168,6 @@ private: // data
bool mFormatChanged;
bool mCompositingFailed;
bool mNonPremult;
/** Indicates if the image data is currently locked */
bool mLocked;
/** Have we called DiscardTracker::InformAllocation()? */
bool mInformedDiscardTracker;