From f62c69e9d3990dff71dcf7539d6b73d5a9c6d265 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Thu, 20 Nov 2014 20:48:01 +0000 Subject: [PATCH] Bug 892910: Deal with newSize becoming empty in CreatePartialBitmapForSurface. r=BenWa This patch deals with the situation where newSize becomes empty and causes a division by 0 in the current code. It also ensures all the callers will abort any potential drawing when CreatePartialBitmapForSurface returns a nullptr. --- gfx/2d/DrawTargetD2D.cpp | 4 +++- gfx/2d/DrawTargetD2D1.cpp | 24 +++++++++++++++++++++++- gfx/2d/HelpersD2D.h | 8 ++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/gfx/2d/DrawTargetD2D.cpp b/gfx/2d/DrawTargetD2D.cpp index 0f7036c0fdc8..0ff00370a524 100644 --- a/gfx/2d/DrawTargetD2D.cpp +++ b/gfx/2d/DrawTargetD2D.cpp @@ -2417,7 +2417,9 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha) bitmap = CreatePartialBitmapForSurface(dataSurf, mTransform, mSize, pat->mExtendMode, mat, mRT, &sourceRect); if (!bitmap) { - return nullptr; + RefPtr colBrush; + mRT->CreateSolidColorBrush(D2D1::ColorF(0, 0), byRef(colBrush)); + return colBrush.forget(); } } break; diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 42cc4b471d21..49bed2767d8f 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -191,6 +191,11 @@ DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface *aSurface, Matrix mat; RefPtr image = GetImageForSurface(aSurface, mat, ExtendMode::CLAMP); + if (!image) { + gfxWarning() << "Couldn't get image for surface."; + return; + } + if (!mat.IsIdentity()) { gfxDebug() << *this << ": At this point complex partial uploads are not supported for Shadow surfaces."; return; @@ -264,12 +269,19 @@ DrawTargetD2D1::MaskSurface(const Pattern &aSource, Point aOffset, const DrawOptions &aOptions) { - PrepareForDrawing(aOptions.mCompositionOp, aSource); + MarkChanged(); RefPtr bitmap; RefPtr image = GetImageForSurface(aMask, ExtendMode::CLAMP); + if (!image) { + gfxWarning() << "Failed to get image for surface."; + return; + } + + PrepareForDrawing(aOptions.mCompositionOp, aSource); + // FillOpacityMask only works if the antialias mode is MODE_ALIASED mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); @@ -305,6 +317,11 @@ DrawTargetD2D1::CopySurface(SourceSurface *aSurface, Matrix mat; RefPtr image = GetImageForSurface(aSurface, mat, ExtendMode::CLAMP); + if (!image) { + gfxWarning() << "Couldn't get image for surface."; + return; + } + if (!mat.IsIdentity()) { gfxDebug() << *this << ": At this point complex partial uploads are not supported for CopySurface."; return; @@ -1256,6 +1273,11 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha) RefPtr imageBrush; RefPtr image = GetImageForSurface(pat->mSurface, mat, pat->mExtendMode, !pat->mSamplingRect.IsEmpty() ? &pat->mSamplingRect : nullptr); + + if (!image) { + return CreateTransparentBlackBrush(); + } + mDC->CreateImageBrush(image, D2D1::ImageBrushProperties(samplingBounds, D2DExtend(pat->mExtendMode), diff --git a/gfx/2d/HelpersD2D.h b/gfx/2d/HelpersD2D.h index 99154976f3bb..9599705c9bde 100644 --- a/gfx/2d/HelpersD2D.h +++ b/gfx/2d/HelpersD2D.h @@ -629,14 +629,18 @@ CreatePartialBitmapForSurface(DataSourceSurface *aSurface, const Matrix &aDestin scaler.ScaleForSize(scaleSize); IntSize newSize = scaler.GetSize(); + + if (newSize.IsEmpty()) { + return nullptr; + } aRT->CreateBitmap(D2D1::SizeU(newSize.width, newSize.height), scaler.GetScaledData(), scaler.GetStride(), D2D1::BitmapProperties(D2DPixelFormat(aSurface->GetFormat())), byRef(bitmap)); - aSourceTransform.PreScale(Float(size.width / newSize.width), - Float(size.height / newSize.height)); + aSourceTransform.PreScale(Float(size.width) / newSize.width, + Float(size.height) / newSize.height); return bitmap.forget(); } }