Bug 1126490 - Part 2: Recover from loss of surfaces in VectorImage. r=dholbert, a=sledru
authorSeth Fowler <seth@mozilla.com>
Tue, 03 Feb 2015 16:35:22 -0800
changeset 243694 3be92206bfd0
parent 243693 b1db02330579
child 243695 4155bf349dbb
push id4440
push userryanvm@gmail.com
push date2015-02-05 16:07 +0000
treeherdermozilla-beta@74c4e5bdde78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, sledru
bugs1126490
milestone36.0
Bug 1126490 - Part 2: Recover from loss of surfaces in VectorImage. r=dholbert, a=sledru
image/src/VectorImage.cpp
image/src/VectorImage.h
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -803,23 +803,29 @@ VectorImage::Draw(gfxContext* aContext,
     SurfaceCache::Lookup(ImageKey(this),
                          VectorSurfaceKey(params.size,
                                           params.svgContext,
                                           params.animationTime));
 
   // Draw.
   if (frameRef) {
     RefPtr<SourceSurface> surface = frameRef->GetSurface();
-    nsRefPtr<gfxDrawable> svgDrawable =
-      new gfxSurfaceDrawable(surface, ThebesIntSize(frameRef->GetSize()));
-    Show(svgDrawable, params);
-  } else {
-    CreateSurfaceAndShow(params);
+    if (surface) {
+      nsRefPtr<gfxDrawable> svgDrawable =
+        new gfxSurfaceDrawable(surface, ThebesIntSize(frameRef->GetSize()));
+      Show(svgDrawable, params);
+      return NS_OK;
+    }
+
+    // We lost our surface due to some catastrophic event.
+    RecoverFromLossOfSurfaces();
   }
 
+  CreateSurfaceAndShow(params);
+
   return NS_OK;
 }
 
 void
 VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams)
 {
   mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize);
   mSVGDocumentWrapper->FlushImageTransformInvalidation();
@@ -885,16 +891,25 @@ VectorImage::Show(gfxDrawable* aDrawable
                              aParams.region,
                              SurfaceFormat::B8G8R8A8,
                              aParams.filter, aParams.flags, aParams.opacity);
 
   MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
   mRenderingObserver->ResumeHonoringInvalidations();
 }
 
+void
+VectorImage::RecoverFromLossOfSurfaces()
+{
+  NS_WARNING("An imgFrame became invalid. Attempting to recover...");
+
+  // Discard all existing frames, since they're probably all now invalid.
+  SurfaceCache::RemoveImage(ImageKey(this));
+}
+
 //******************************************************************************
 /* void requestDecode() */
 NS_IMETHODIMP
 VectorImage::RequestDecode()
 {
   // Nothing to do for SVG images
   return NS_OK;
 }
--- a/image/src/VectorImage.h
+++ b/image/src/VectorImage.h
@@ -81,16 +81,23 @@ protected:
   virtual nsresult StartAnimation();
   virtual nsresult StopAnimation();
   virtual bool     ShouldAnimate();
 
   void CreateSurfaceAndShow(const SVGDrawingParameters& aParams);
   void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);
 
 private:
+  /**
+   * In catastrophic circumstances like a GPU driver crash, we may lose our
+   * surfaces even if they're locked. RecoverFromLossOfSurfaces discards all
+   * existing surfaces, allowing us to recover.
+   */
+  void RecoverFromLossOfSurfaces();
+
   void CancelAllListeners();
   void SendInvalidationNotifications();
 
   nsRefPtr<SVGDocumentWrapper>       mSVGDocumentWrapper;
   nsRefPtr<SVGRootRenderingObserver> mRenderingObserver;
   nsRefPtr<SVGLoadEventListener>     mLoadEventListener;
   nsRefPtr<SVGParseCompleteListener> mParseCompleteListener;