Bug 1130195: Report the failed bitmap creation, but still crash. r=bschouten
authorMilan Sreckovic <milan@mozilla.com>
Wed, 25 Feb 2015 17:44:56 -0500
changeset 230835 0b2ba97230d602e1d74b02037abe6758d248ceb9
parent 230834 dd6aba52db7039fd0482c26e6f8fe9963249fc30
child 230836 50b89dc937500f401136f2ba799bb3f804bf317c
push id28337
push usercbook@mozilla.com
push dateThu, 26 Feb 2015 10:57:44 +0000
treeherdermozilla-central@599b84826bf3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbschouten
bugs1130195
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1130195: Report the failed bitmap creation, but still crash. r=bschouten
gfx/2d/DrawTargetD2D.cpp
gfx/2d/DrawTargetD2D1.cpp
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -133,24 +133,28 @@ public:
     factory()->CreatePathGeometry(byRef(invClippedArea));
     RefPtr<ID2D1GeometrySink> sink;
     invClippedArea->Open(byRef(sink));
 
     rectGeom->CombineWithGeometry(mClippedArea, D2D1_COMBINE_MODE_EXCLUDE, nullptr, sink);
     sink->Close();
 
     RefPtr<ID2D1BitmapBrush> brush;
-    rt->CreateBitmapBrush(mOldSurfBitmap, D2D1::BitmapBrushProperties(), D2D1::BrushProperties(), byRef(brush));                   
+    HRESULT hr = rt->CreateBitmapBrush(mOldSurfBitmap, D2D1::BitmapBrushProperties(), D2D1::BrushProperties(), byRef(brush));
+    if (FAILED(hr)) {
+      gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D] CreateBitmapBrush failure " << hexa(hr);
+      return;
+    }
 
     rt->FillGeometry(invClippedArea, brush);
   }
 
 private:
 
-  DrawTargetD2D *mDT;  
+  DrawTargetD2D *mDT;
 
   // If we have an operator unbound by the source, this will contain a bitmap
   // with the old dest surface data.
   RefPtr<ID2D1Bitmap> mOldSurfBitmap;
   // This contains the area drawing is clipped to.
   RefPtr<ID2D1Geometry> mClippedArea;
 };
 
@@ -303,17 +307,22 @@ DrawTargetD2D::GetBitmapForSurface(Sourc
       int stride = srcSurf->Stride();
 
       unsigned char *data = srcSurf->GetData() +
                             (uint32_t)sourceRect.y * stride +
                             (uint32_t)sourceRect.x * BytesPerPixel(srcSurf->GetFormat());
 
       D2D1_BITMAP_PROPERTIES props =
         D2D1::BitmapProperties(D2DPixelFormat(srcSurf->GetFormat()));
-      mRT->CreateBitmap(D2D1::SizeU(UINT32(sourceRect.width), UINT32(sourceRect.height)), data, stride, props, byRef(bitmap));
+      HRESULT hr = mRT->CreateBitmap(D2D1::SizeU(UINT32(sourceRect.width), UINT32(sourceRect.height)), data, stride, props, byRef(bitmap));
+      if (FAILED(hr)) {
+        IntSize size(sourceRect.width, sourceRect.height);
+        gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1CreateBitmap failure " << size << " Code: " << hexa(hr);
+        return nullptr;
+      }
 
       // subtract the integer part leaving the fractional part
       aSource.x -= (uint32_t)aSource.x;
       aSource.y -= (uint32_t)aSource.y;
     }
     break;
   }
 
@@ -2410,24 +2419,27 @@ DrawTargetD2D::CreateBrushForPattern(con
         if (!bitmap) {
           RefPtr<ID2D1SolidColorBrush> colBrush;
           mRT->CreateSolidColorBrush(D2D1::ColorF(0, 0), byRef(colBrush));
           return colBrush.forget();
         }
       }
       break;
     }
-    
-    mRT->CreateBitmapBrush(bitmap,
+
+    HRESULT hr = mRT->CreateBitmapBrush(bitmap,
                            D2D1::BitmapBrushProperties(D2DExtend(pat->mExtendMode),
                                                        D2DExtend(pat->mExtendMode),
                                                        D2DFilter(pat->mFilter)),
                            D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
                            byRef(bmBrush));
-
+    if (FAILED(hr)) {
+      gfxCriticalError() << "[D2D] 1CreateBitmapBrush failure: " << hexa(hr);
+      return nullptr;
+    }
     return bmBrush.forget();
   }
 
   gfxWarning() << "Invalid pattern type detected.";
   return nullptr;
 }
 
 TemporaryRef<ID3D10Texture2D>
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -822,17 +822,17 @@ DrawTargetD2D1::Init(const IntSize &aSiz
   }
 
   props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
   props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
 
   hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mTempBitmap));
 
   if (FAILED(hr)) {
-    gfxCriticalError() << "[D2D1.1] failed to create new TempBitmap " << aSize << " Code: " << hexa(hr);
+    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D2D1.1] failed to create new TempBitmap " << aSize << " Code: " << hexa(hr);
     return false;
   }
 
   mDC->SetTarget(mBitmap);
 
   mDC->BeginDraw();
 
   mDC->Clear();
@@ -960,17 +960,23 @@ DrawTargetD2D1::FinalizeDrawing(Composit
 
       if (!mBlendEffect) {
         gfxWarning() << "Failed to create blend effect!";
         return;
       }
     }
 
     RefPtr<ID2D1Bitmap> tmpBitmap;
-    mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
+    HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
+    if (FAILED(hr)) {
+      gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 5CreateBitmap failure " << mSize << " Code: " << hexa(hr);
+      // For now, crash in this scenario; this should happen because tmpBitmap is
+      // null and CopyFromBitmap call below dereferences it.
+      // return;
+    }
 
     // This flush is important since the copy method will not know about the context drawing to the surface.
     // We also need to pop all the clips to make sure any drawn content will have made it to the final bitmap.
     PopAllClips();
     mDC->Flush();
 
     // We need to use a copy here because affects don't accept a surface on
     // both their in- and outputs.