Bug 844819 - Don't create DrawTargets for invalid cairo surfaces. r=Bas, a=lsblakk
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 24 Oct 2013 16:35:29 +0200
changeset 286430 2a42d4d730da1772f079171e456a40b229dabe7b
parent 286429 bfd0f8d7509f3395381fb651015de16a166701bc
child 286431 f6c045df71a672b4171ed5a3416877b898384505
push id218
push userryanvm@gmail.com
push dateWed, 16 Dec 2015 22:58:33 +0000
reviewersBas, lsblakk
bugs844819
milestone26.0
Bug 844819 - Don't create DrawTargets for invalid cairo surfaces. r=Bas, a=lsblakk
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxPlatform.cpp
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -562,16 +562,20 @@ gfxContext::DrawSurface(gfxASurface *sur
 
     cairo_fill(mCairo);
     cairo_restore(mCairo);
   } else {
     // Lifetime needs to be limited here since we may wrap surface's data.
     RefPtr<SourceSurface> surf =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
 
+    if (!surf) {
+      return;
+    }
+
     Rect rect(0, 0, Float(size.width), Float(size.height));
     rect.Intersect(Rect(0, 0, Float(surf->GetSize().width), Float(surf->GetSize().height)));
 
     // XXX - Should fix pixel snapping.
     mDT->DrawSurface(surf, rect, rect);
   }
 }
 
@@ -1378,16 +1382,17 @@ gfxContext::SetSource(gfxASurface *surfa
     CurrentState().surfTransform = Matrix(1.0f, 0, 0, 1.0f, Float(offset.x), Float(offset.y));
     CurrentState().pattern = nullptr;
     CurrentState().patternTransformChanged = false;
     // Keep the underlying cairo surface around while we keep the
     // sourceSurface.
     CurrentState().sourceSurfCairo = surface;
     CurrentState().sourceSurface =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
+    CurrentState().color = Color(0, 0, 0, 0);
   }
 }
 
 void
 gfxContext::SetPattern(gfxPattern *pattern)
 {
   if (mCairo) {
     cairo_set_source(mCairo, pattern->CairoPattern());
@@ -1481,16 +1486,20 @@ gfxContext::Mask(gfxASurface *surface, c
   PROFILER_LABEL("gfxContext", "Mask");
   if (mCairo) {
     cairo_mask_surface(mCairo, surface->CairoSurface(), offset.x, offset.y);
   } else {
     // Lifetime needs to be limited here as we may simply wrap surface's data.
     RefPtr<SourceSurface> sourceSurf =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
 
+    if (!sourceSurf) {
+      return;
+    }
+
     gfxPoint pt = surface->GetDeviceOffset();
 
     // We clip here to bind to the mask surface bounds, see above.
     mDT->MaskSurface(GeneralPattern(this), 
               sourceSurf,
               Point(offset.x - pt.x, offset.y -  pt.y),
               DrawOptions(1.0f, CurrentState().op, CurrentState().aaMode));
   }
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -640,16 +640,20 @@ void
 gfxPlatform::ClearSourceSurfaceForSurface(gfxASurface *aSurface)
 {
   aSurface->SetData(&kSourceSurface, nullptr, nullptr);
 }
 
 RefPtr<SourceSurface>
 gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurface)
 {
+  if (!aSurface->CairoSurface() || aSurface->CairoStatus()) {
+    return nullptr;
+  }
+
   void *userData = aSurface->GetData(&kSourceSurface);
 
   if (userData) {
     SourceSurfaceUserData *surf = static_cast<SourceSurfaceUserData*>(userData);
 
     if (surf->mSrcSurface->IsValid() && surf->mBackendType == aTarget->GetType()) {
       return surf->mSrcSurface;
     }
@@ -736,20 +740,16 @@ gfxPlatform::GetSourceSurfaceForSurface(
                                                      imgSurface->Stride(),
                                                      format);
 
     if (!srcBuffer) {
       // We need to check if our gfxASurface will keep the underlying data
       // alive. This is true if gfxASurface actually -is- an ImageSurface or
       // if it is a gfxWindowsSurface which supports GetAsImageSurface.
       if (imgSurface != aSurface && !isWin32ImageSurf) {
-        // This shouldn't happen for now, it can be easily supported by making
-        // a copy. For now let's just abort.
-        NS_RUNTIMEABORT("Attempt to create unsupported SourceSurface from"
-            "non-image surface.");
         return nullptr;
       }
 
       srcBuffer = Factory::CreateWrappingDataSourceSurface(imgSurface->Data(),
                                                            imgSurface->Stride(),
                                                            size, format);
 
     }