diff --git a/image/AutoRestoreSVGState.h b/image/AutoRestoreSVGState.h index 407c61c1974f..3a5708c63ac6 100644 --- a/image/AutoRestoreSVGState.h +++ b/image/AutoRestoreSVGState.h @@ -19,9 +19,9 @@ namespace image { class MOZ_STACK_CLASS AutoRestoreSVGState final { public: AutoRestoreSVGState(const SVGDrawingParameters& aParams, - SVGDocumentWrapper* aSVGDocumentWrapper, bool& aIsDrawing, + SVGDocumentWrapper* aSVGDocumentWrapper, bool aContextPaint) - : mIsDrawing(aIsDrawing) + : mIsDrawing(aSVGDocumentWrapper->mIsDrawing) // Apply any 'preserveAspectRatio' override (if specified) to the root // element: , @@ -29,10 +29,10 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final { // Set the animation time: , mTime(aSVGDocumentWrapper->GetRootSVGElem(), aParams.animationTime) { - MOZ_ASSERT(!aIsDrawing); + MOZ_ASSERT(!mIsDrawing.SavedValue()); MOZ_ASSERT(aSVGDocumentWrapper->GetDocument()); - aIsDrawing = true; + aSVGDocumentWrapper->mIsDrawing = true; // Set context paint (if specified) on the document: if (aContextPaint) { diff --git a/image/SVGDocumentWrapper.cpp b/image/SVGDocumentWrapper.cpp index 386e209ea90a..a85176db49e1 100644 --- a/image/SVGDocumentWrapper.cpp +++ b/image/SVGDocumentWrapper.cpp @@ -42,7 +42,9 @@ NS_IMPL_ISUPPORTS(SVGDocumentWrapper, nsIStreamListener, nsIRequestObserver, nsIObserver, nsISupportsWeakReference) SVGDocumentWrapper::SVGDocumentWrapper() - : mIgnoreInvalidation(false), mRegisteredForXPCOMShutdown(false) {} + : mIgnoreInvalidation(false), + mRegisteredForXPCOMShutdown(false), + mIsDrawing(false) {} SVGDocumentWrapper::~SVGDocumentWrapper() { DestroyViewer(); diff --git a/image/SVGDocumentWrapper.h b/image/SVGDocumentWrapper.h index f5cc74f0aa44..75924a4ea581 100644 --- a/image/SVGDocumentWrapper.h +++ b/image/SVGDocumentWrapper.h @@ -31,10 +31,11 @@ class SVGDocument; } // namespace dom namespace image { +class AutoRestoreSVGState; class SVGDocumentWrapper final : public nsIStreamListener, public nsIObserver, - nsSupportsWeakReference { + public nsSupportsWeakReference { public: SVGDocumentWrapper(); @@ -101,6 +102,13 @@ class SVGDocumentWrapper final : public nsIStreamListener, */ bool ShouldIgnoreInvalidation() { return mIgnoreInvalidation; } + /** + * Returns a bool indicating whether the document is currently drawing. + * + * @return true if the document is drawing. Else, false. + */ + bool IsDrawing() const { return mIsDrawing; } + /** * Methods to control animation. */ @@ -117,6 +125,8 @@ class SVGDocumentWrapper final : public nsIStreamListener, void FlushLayout(); private: + friend class AutoRestoreSVGState; + ~SVGDocumentWrapper(); nsresult SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer, @@ -130,9 +140,18 @@ class SVGDocumentWrapper final : public nsIStreamListener, nsCOMPtr mListener; bool mIgnoreInvalidation; bool mRegisteredForXPCOMShutdown; + bool mIsDrawing; }; } // namespace image } // namespace mozilla +/** + * Casting SVGDocumentWrapper to nsISupports is ambiguous. This method handles + * that. + */ +inline nsISupports* ToSupports(mozilla::image::SVGDocumentWrapper* p) { + return NS_ISUPPORTS_CAST(nsSupportsWeakReference*, p); +} + #endif // mozilla_image_SVGDocumentWrapper_h diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 49238fd4441d..1de6e111c4aa 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -309,7 +309,6 @@ VectorImage::VectorImage(nsIURI* aURI /* = nullptr */) mIsInitialized(false), mDiscardable(false), mIsFullyLoaded(false), - mIsDrawing(false), mHaveAnimations(false), mHasPendingInvalidation(false) {} @@ -717,7 +716,7 @@ VectorImage::GetFrameInternal(const IntSize& aSize, std::move(sourceSurface)); } - if (mIsDrawing) { + if (mSVGDocumentWrapper->IsDrawing()) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return MakeTuple(ImgDrawResult::TEMPORARY_ERROR, decodeSize, RefPtr()); @@ -736,8 +735,7 @@ VectorImage::GetFrameInternal(const IntSize& aSize, bool didCache; // Was the surface put into the cache? bool contextPaint = aSVGContext && aSVGContext->GetContextPaint(); - AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, mIsDrawing, - contextPaint); + AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, contextPaint); RefPtr svgDrawable = CreateSVGDrawable(params); RefPtr surface = CreateSurface(params, svgDrawable, didCache); @@ -935,13 +933,12 @@ VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, // else, we need to paint the image: - if (mIsDrawing) { + if (mSVGDocumentWrapper->IsDrawing()) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return ImgDrawResult::TEMPORARY_ERROR; } - AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, mIsDrawing, - contextPaint); + AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, contextPaint); bool didCache; // Was the surface put into the cache? RefPtr svgDrawable = CreateSVGDrawable(params); @@ -1014,7 +1011,7 @@ Tuple, IntSize> VectorImage::LookupCachedSurface( already_AddRefed VectorImage::CreateSurface( const SVGDrawingParameters& aParams, gfxDrawable* aSVGDrawable, bool& aWillCache) { - MOZ_ASSERT(mIsDrawing); + MOZ_ASSERT(mSVGDocumentWrapper->IsDrawing()); mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize); mSVGDocumentWrapper->FlushImageTransformInvalidation(); diff --git a/image/VectorImage.h b/image/VectorImage.h index d0a8ab42d232..6b7e13ce394d 100644 --- a/image/VectorImage.h +++ b/image/VectorImage.h @@ -150,7 +150,6 @@ class VectorImage final : public ImageResource, public nsIStreamListener { bool mDiscardable; // Are we discardable? bool mIsFullyLoaded; // Has the SVG document finished // loading? - bool mIsDrawing; // Are we currently drawing? bool mHaveAnimations; // Is our SVG content SMIL-animated? // (Only set after mIsFullyLoaded.) bool mHasPendingInvalidation; // Invalidate observers next refresh