Bug 1575838: Check that we can create a similar DrawTarget first in canvas Adjusted targets. r=mattwoodrow
authorBob Owen <bobowencode@gmail.com>
Fri, 30 Aug 2019 17:14:44 +0000
changeset 551415 f0e1e0d729d2d0b1ae888dba7ff0851593b9ee58
parent 551414 653ffc92a954626c649bac11255c41223316fd79
child 551416 79eedeada42cf25a011a184250e2f407c1333d67
push id11865
push userbtara@mozilla.com
push dateMon, 02 Sep 2019 08:54:37 +0000
treeherdermozilla-beta@37f59c4671b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1575838
milestone70.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 1575838: Check that we can create a similar DrawTarget first in canvas Adjusted targets. r=mattwoodrow This also fixes DrawTargetSkia::CanCreateSimilarDrawTarget because currently if only one of the height or width is negative then it doesn't get caught. Differential Revision: https://phabricator.services.mozilla.com/D43075
dom/canvas/CanvasRenderingContext2D.cpp
gfx/2d/DrawTargetSkia.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -354,16 +354,24 @@ class AdjustedTargetForFilter {
 
     if (mSourceGraphicRect.IsEmpty()) {
       // The filter might not make any use of the source graphic. We need to
       // create a DrawTarget that we can return from DT() anyway, so we'll
       // just use a 1x1-sized one.
       mSourceGraphicRect.SizeTo(1, 1);
     }
 
+    if (!mFinalTarget->CanCreateSimilarDrawTarget(mSourceGraphicRect.Size(),
+                                                  SurfaceFormat::B8G8R8A8)) {
+      mTarget = mFinalTarget;
+      mCtx = nullptr;
+      mFinalTarget = nullptr;
+      return;
+    }
+
     mTarget = mFinalTarget->CreateSimilarDrawTarget(mSourceGraphicRect.Size(),
                                                     SurfaceFormat::B8G8R8A8);
 
     if (mTarget) {
       // See bug 1524554.
       mTarget->ClearRect(gfx::Rect());
     }
 
@@ -476,16 +484,24 @@ class AdjustedTargetForShadow {
     // easier to execute the actual blur on hardware, and shouldn't affect
     // the amount of pixels that need to be touched.
     gfx::Rect bounds = aBounds;
     int32_t blurRadius = state.ShadowBlurRadius();
     bounds.Inflate(blurRadius);
     bounds.RoundOut();
     bounds.ToIntRect(&mTempRect);
 
+    if (!mFinalTarget->CanCreateSimilarDrawTarget(mTempRect.Size(),
+                                                  SurfaceFormat::B8G8R8A8)) {
+      mTarget = mFinalTarget;
+      mCtx = nullptr;
+      mFinalTarget = nullptr;
+      return;
+    }
+
     mTarget = mFinalTarget->CreateShadowDrawTarget(
         mTempRect.Size(), SurfaceFormat::B8G8R8A8, mSigma);
 
     if (mTarget) {
       // See bug 1524554.
       mTarget->ClearRect(gfx::Rect());
     }
 
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -1593,17 +1593,19 @@ already_AddRefed<DrawTarget> DrawTargetS
   if (!target->Init(aSize, aFormat)) {
     return nullptr;
   }
   return target.forget();
 }
 
 bool DrawTargetSkia::CanCreateSimilarDrawTarget(const IntSize& aSize,
                                                 SurfaceFormat aFormat) const {
-  return size_t(std::max(aSize.width, aSize.height)) < GetMaxSurfaceSize();
+  auto minmaxPair = std::minmax(aSize.width, aSize.height);
+  return minmaxPair.first >= 0 &&
+         size_t(minmaxPair.second) < GetMaxSurfaceSize();
 }
 
 RefPtr<DrawTarget> DrawTargetSkia::CreateClippedDrawTarget(
     const Rect& aBounds, SurfaceFormat aFormat) {
   SkIRect clipBounds;
 
   RefPtr<DrawTarget> result;
   // Doing this save()/restore() dance is wasteful