Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn

This commit is contained in:
Seth Fowler 2015-09-19 16:21:02 -07:00
parent 7eae9e022f
commit 6e3870990e
2 changed files with 5 additions and 83 deletions

View File

@ -796,88 +796,8 @@ imgFrame::LockImageData()
return NS_OK;
}
return Deoptimize();
}
nsresult
imgFrame::Deoptimize()
{
MOZ_ASSERT(NS_IsMainThread());
mMonitor.AssertCurrentThreadOwns();
MOZ_ASSERT(!mImageSurface);
if (!mImageSurface) {
if (mVBuf) {
VolatileBufferPtr<uint8_t> ref(mVBuf);
if (ref.WasBufferPurged()) {
return NS_ERROR_FAILURE;
}
mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat);
if (!mImageSurface) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
if (mOptSurface || mSinglePixel || mFormat == SurfaceFormat::R5G6B5) {
SurfaceFormat format = mFormat;
if (mFormat == SurfaceFormat::R5G6B5) {
format = SurfaceFormat::B8G8R8A8;
}
// Recover the pixels
RefPtr<VolatileBuffer> buf =
AllocateBufferForImage(mSize, format);
if (!buf) {
return NS_ERROR_OUT_OF_MEMORY;
}
RefPtr<DataSourceSurface> surf =
CreateLockedSurface(buf, mSize, format);
if (!surf) {
return NS_ERROR_OUT_OF_MEMORY;
}
DataSourceSurface::MappedSurface mapping;
if (!surf->Map(DataSourceSurface::MapType::WRITE, &mapping)) {
gfxCriticalError() << "imgFrame::Deoptimize failed to map surface";
return NS_ERROR_FAILURE;
}
RefPtr<DrawTarget> target =
Factory::CreateDrawTargetForData(BackendType::CAIRO,
mapping.mData,
mSize,
mapping.mStride,
format);
if (!target) {
gfxWarning() <<
"imgFrame::Deoptimize failed in CreateDrawTargetForData";
return NS_ERROR_OUT_OF_MEMORY;
}
Rect rect(0, 0, mSize.width, mSize.height);
if (mSinglePixel) {
target->FillRect(rect, ColorPattern(mSinglePixelColor),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
} else if (mFormat == SurfaceFormat::R5G6B5) {
target->DrawSurface(mImageSurface, rect, rect);
} else {
target->DrawSurface(mOptSurface, rect, rect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
}
target->Flush();
surf->Unmap();
mFormat = format;
mVBuf = buf;
mImageSurface = surf;
mOptSurface = nullptr;
}
}
mVBufPtr = mVBuf;
return NS_OK;
MOZ_ASSERT_UNREACHABLE("It's illegal to re-lock an optimized imgFrame");
return NS_ERROR_FAILURE;
}
void

View File

@ -274,7 +274,6 @@ private: // methods
nsresult LockImageData();
nsresult UnlockImageData();
nsresult Optimize();
nsresult Deoptimize();
void AssertImageDataLocked() const;
@ -448,6 +447,9 @@ private:
* This may be considerably more expensive than is necessary just for drawing,
* so only use this when you need to read or write the raw underlying image data
* that the imgFrame holds.
*
* Once all an imgFrame's RawAccessFrameRefs go out of scope, new
* RawAccessFrameRefs cannot be created.
*/
class RawAccessFrameRef final
{