diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 8db454bed014..323795432985 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -859,34 +859,47 @@ VectorImage::Draw(gfxContext* aContext, SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter, svgContext, animTime, aFlags); - if (aFlags & FLAG_BYPASS_SURFACE_CACHE) { - CreateSurfaceAndShow(params); + // If we have an prerasterized version of this image that matches the + // drawing parameters, use that. + RefPtr svgDrawable = LookupCachedSurface(params); + if (svgDrawable) { + Show(svgDrawable, params); return DrawResult::SUCCESS; } + // We didn't get a hit in the surface cache, so we'll need to rerasterize. + CreateSurfaceAndShow(params); + return DrawResult::SUCCESS; +} + +already_AddRefed +VectorImage::LookupCachedSurface(const SVGDrawingParameters& aParams) +{ + // If we're not allowed to use a cached surface, don't attempt a lookup. + if (aParams.flags & FLAG_BYPASS_SURFACE_CACHE) { + return nullptr; + } + LookupResult result = SurfaceCache::Lookup(ImageKey(this), - VectorSurfaceKey(params.size, - params.svgContext, - params.animationTime)); - - // Draw. - if (result) { - RefPtr sourceSurface = result.Surface()->GetSourceSurface(); - if (sourceSurface) { - RefPtr svgDrawable = - new gfxSurfaceDrawable(sourceSurface, result.Surface()->GetSize()); - Show(svgDrawable, params); - return DrawResult::SUCCESS; - } - - // We lost our surface due to some catastrophic event. - RecoverFromLossOfSurfaces(); + VectorSurfaceKey(aParams.size, + aParams.svgContext, + aParams.animationTime)); + if (!result) { + return nullptr; // No matching surface, or the OS freed the volatile buffer. } - CreateSurfaceAndShow(params); + RefPtr sourceSurface = result.Surface()->GetSourceSurface(); + if (!sourceSurface) { + // Something went wrong. (Probably a GPU driver crash or device reset.) + // Attempt to recover. + RecoverFromLossOfSurfaces(); + return nullptr; + } - return DrawResult::SUCCESS; + RefPtr svgDrawable = + new gfxSurfaceDrawable(sourceSurface, result.Surface()->GetSize()); + return svgDrawable.forget(); } void diff --git a/image/VectorImage.h b/image/VectorImage.h index 3bbe4a813bb0..3753785975c5 100644 --- a/image/VectorImage.h +++ b/image/VectorImage.h @@ -78,10 +78,14 @@ protected: virtual nsresult StopAnimation() override; virtual bool ShouldAnimate() override; +private: + /// Attempt to find a cached surface matching @aParams in the SurfaceCache. + already_AddRefed + LookupCachedSurface(const SVGDrawingParameters& aParams); + void CreateSurfaceAndShow(const SVGDrawingParameters& aParams); void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams); -private: nsresult Init(const char* aMimeType, uint32_t aFlags); /**