Bug 1089046 (Part 2) - Remove guards against recursive notifications. r=tn

This commit is contained in:
Seth Fowler 2014-11-14 20:06:21 -08:00
Родитель d9d70fd0bf
Коммит d21b3e2c48
2 изменённых файлов: 3 добавлений и 83 удалений

Просмотреть файл

@ -320,7 +320,6 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
#endif
mDecodingMonitor("RasterImage Decoding Monitor"),
mDecoder(nullptr),
mInDecoder(false),
mStatusDiff(ImageStatusDiff::NoChange()),
mNotifying(false),
mHasSize(false),
@ -331,8 +330,6 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
mDecoded(false),
mHasBeenDecoded(false),
mAnimationFinished(false),
mFinishing(false),
mInUpdateImageContainer(false),
mWantFullDecode(false),
mPendingError(false)
{
@ -778,10 +775,6 @@ RasterImage::CopyFrame(uint32_t aWhichFrame,
if (mError)
return nullptr;
// Disallowed in the API
if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
return nullptr;
if (!ApplyDecodeFlags(aFlags, aWhichFrame))
return nullptr;
@ -859,10 +852,6 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame,
if (mError)
return nullptr;
// Disallowed in the API
if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
return nullptr;
if (!ApplyDecodeFlags(aFlags, aWhichFrame))
return nullptr;
@ -968,18 +957,16 @@ RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
void
RasterImage::UpdateImageContainer()
{
if (!mImageContainer || IsInUpdateImageContainer()) {
if (!mImageContainer) {
return;
}
SetInUpdateImageContainer(true);
nsRefPtr<layers::Image> image = GetCurrentImage();
if (!image) {
return;
}
mImageContainer->SetCurrentImage(image);
SetInUpdateImageContainer(false);
}
size_t
@ -1530,9 +1517,6 @@ RasterImage::AddSourceData(const char *aBuffer, uint32_t aCount)
NS_ABORT_IF_FALSE(!mHasSourceData, "Calling AddSourceData() after calling "
"sourceDataComplete()!");
// This call should come straight from necko - no reentrancy allowed
NS_ABORT_IF_FALSE(!mInDecoder, "Re-entrant call to AddSourceData!");
// Image is already decoded, we shouldn't be getting data, but it could
// be extra garbage data at the end of a file.
if (mDecoded) {
@ -2049,11 +2033,7 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
nsRefPtr<Decoder> decoder = mDecoder;
mDecoder = nullptr;
mFinishing = true;
mInDecoder = true;
decoder->Finish(aIntent);
mInDecoder = false;
mFinishing = false;
// Unlock the last frame (if we have any). Our invariant is that, while we
// have a decoder open, the last frame is always locked.
@ -2104,9 +2084,7 @@ RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy
// Write
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = true;
mDecoder->Write(aBuffer, aCount, aStrategy);
mInDecoder = false;
CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError());
@ -2186,28 +2164,11 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
if (mDecoded)
return NS_OK;
// mFinishing protects against the case when we enter RequestDecode from
// ShutdownDecoder -- in that case, we're done with the decode, we're just
// not quite ready to admit it. See bug 744309.
if (mFinishing)
return NS_OK;
// If we're currently waiting for a new frame, we can't do anything until
// that frame is allocated.
if (mDecoder && mDecoder->NeedsNewFrame())
return NS_OK;
// If our callstack goes through a size decoder, we have a problem.
// We need to shutdown the size decode and replace it with a full
// decoder, but can't do that from within the decoder itself. Thus, we post
// an asynchronous event to the event loop to do it later. Since
// RequestDecode() is an asynchronous function this works fine (though it's
// a little slower).
if (mInDecoder) {
nsRefPtr<imgDecodeRequestor> requestor = new imgDecodeRequestor(*this);
return NS_DispatchToCurrentThread(requestor);
}
// If we have a size decoder open, make sure we get the size
if (mDecoder && mDecoder->IsSizeDecode()) {
nsresult rv = DecodePool::Singleton()->DecodeUntilSizeAvailable(this);
@ -2306,7 +2267,7 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
// If we can do decoding now, do so. Small images will decode completely,
// large images will decode a bit and post themselves to the event loop
// to finish decoding.
if (!mDecoded && !mInDecoder && mHasSourceData && aDecodeType == SYNCHRONOUS_NOTIFY_AND_SOME_DECODE) {
if (!mDecoded && mHasSourceData && aDecodeType == SYNCHRONOUS_NOTIFY_AND_SOME_DECODE) {
PROFILER_LABEL_PRINTF("RasterImage", "DecodeABitOf",
js::ProfileEntry::Category::GRAPHICS, "%s", GetURIString().get());
@ -2346,12 +2307,6 @@ RasterImage::SyncDecode()
ReentrantMonitorAutoEnter lock(mDecodingMonitor);
// We really have no good way of forcing a synchronous decode if we're being
// called in a re-entrant manner (ie, from an event listener fired by a
// decoder), because the decoding machinery is already tied up. We thus explicitly
// disallow this type of call in the API, and check for it in API methods.
NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!");
if (mDecodeRequest) {
// If the image is waiting for decode work to be notified, go ahead and do that.
if (mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
@ -2602,10 +2557,6 @@ RasterImage::Draw(gfxContext* aContext,
if (mError)
return NS_ERROR_FAILURE;
// Disallowed in the API
if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
return NS_ERROR_FAILURE;
// Illegal -- you can't draw with non-default decode flags.
// (Disabling colorspace conversion might make sense to allow, but
// we don't currently.)

Просмотреть файл

@ -558,8 +558,6 @@ private:
already_AddRefed<layers::Image> GetCurrentImage();
void UpdateImageContainer();
void SetInUpdateImageContainer(bool aInUpdate) { mInUpdateImageContainer = aInUpdate; }
bool IsInUpdateImageContainer() { return mInUpdateImageContainer; }
enum RequestDecodeType {
ASYNCHRONOUS,
SYNCHRONOUS_NOTIFY,
@ -640,8 +638,6 @@ private: // data
// Decoder and friends
nsRefPtr<Decoder> mDecoder;
nsRefPtr<DecodeRequest> mDecodeRequest;
bool mInDecoder;
// END LOCKED MEMBER VARIABLES
// Notification state. Used to avoid recursive notifications.
@ -665,11 +661,6 @@ private: // data
// of frames, or no more owning request
bool mAnimationFinished:1;
// Whether we're calling Decoder::Finish() from ShutdownDecoder.
bool mFinishing:1;
bool mInUpdateImageContainer:1;
// Whether, once we are done doing a size decode, we should immediately kick
// off a full decode.
bool mWantFullDecode:1;
@ -755,28 +746,6 @@ inline NS_IMETHODIMP RasterImage::GetAnimationMode(uint16_t *aAnimationMode) {
return GetAnimationModeInternal(aAnimationMode);
}
// Asynchronous Decode Requestor
//
// We use this class when someone calls requestDecode() from within a decode
// notification. Since requestDecode() involves modifying the decoder's state
// (for example, possibly shutting down a header-only decode and starting a
// full decode), we don't want to do this from inside a decoder.
class imgDecodeRequestor : public nsRunnable
{
public:
explicit imgDecodeRequestor(RasterImage &aContainer) {
mContainer = &aContainer;
}
NS_IMETHOD Run() {
if (mContainer)
mContainer->StartDecoding();
return NS_OK;
}
private:
WeakPtr<RasterImage> mContainer;
};
} // namespace image
} // namespace mozilla