Bug 1524554 - Part 3: Ensure DT validation in internal Canvas fallback path. r=rhunt
authorBas Schouten <bschouten@mozilla.com>
Mon, 11 Mar 2019 14:16:14 +0100
changeset 521675 c4896662a24a
parent 521558 581eed270cff
child 521676 2cb7104e9c84
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt
bugs1524554
milestone67.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 1524554 - Part 3: Ensure DT validation in internal Canvas fallback path. r=rhunt Differential Revision: https://phabricator.services.mozilla.com/D22964
dom/canvas/CanvasRenderingContext2D.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -896,33 +896,32 @@ NS_INTERFACE_MAP_END
  **/
 
 // Initialize our static variables.
 uintptr_t CanvasRenderingContext2D::sNumLivingContexts = 0;
 DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
 
 CanvasRenderingContext2D::CanvasRenderingContext2D(
     layers::LayersBackend aCompositorBackend)
-    : // these are the default values from the Canvas spec
+    :  // these are the default values from the Canvas spec
       mWidth(0),
       mHeight(0),
       mZero(false),
       mOpaqueAttrValue(false),
       mContextAttributesHasAlpha(true),
       mOpaque(false),
       mResetLayer(true),
       mIPC(false),
       mHasPendingStableStateCallback(false),
       mIsEntireFrameInvalid(false),
       mPredictManyRedrawCalls(false),
       mIsCapturedFrameInvalid(false),
       mPathTransformWillUpdate(false),
       mInvalidateCount(0),
       mWriteOnly(false) {
-
   sNumLivingContexts++;
 
   mShutdownObserver = new CanvasShutdownObserver(this);
   nsContentUtils::RegisterShutdownObserver(mShutdownObserver);
 }
 
 CanvasRenderingContext2D::~CanvasRenderingContext2D() {
   RemovePostRefreshObserver();
@@ -1100,18 +1099,17 @@ void CanvasRenderingContext2D::Redraw(co
     return;
   }
 
   SVGObserverUtils::InvalidateDirectRenderingObservers(mCanvasElement);
 
   mCanvasElement->InvalidateCanvasContent(&aR);
 }
 
-void CanvasRenderingContext2D::DidRefresh() {
-}
+void CanvasRenderingContext2D::DidRefresh() {}
 
 void CanvasRenderingContext2D::RedrawUser(const gfxRect& aR) {
   mIsCapturedFrameInvalid = true;
 
   if (mIsEntireFrameInvalid) {
     ++mInvalidateCount;
     return;
   }
@@ -1129,18 +1127,17 @@ bool CanvasRenderingContext2D::CopyBuffe
     return false;
   }
 
   aTarget.CopySurface(snapshot, aCopyRect, IntPoint());
   aOld.ReturnSnapshot(snapshot.forget());
   return true;
 }
 
-void CanvasRenderingContext2D::Demote() {
-}
+void CanvasRenderingContext2D::Demote() {}
 
 void CanvasRenderingContext2D::ScheduleStableStateCallback() {
   if (mHasPendingStableStateCallback) {
     return;
   }
   mHasPendingStableStateCallback = true;
 
   nsContentUtils::RunInStableState(
@@ -1178,18 +1175,18 @@ void CanvasRenderingContext2D::RestoreCl
         mTarget->PushClip(clipOrTransform.clip);
       } else {
         mTarget->SetTransform(clipOrTransform.transform);
       }
     }
   }
 }
 
-bool CanvasRenderingContext2D::EnsureTarget(
-    const gfx::Rect* aCoveredRect, bool aWillClear) {
+bool CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
+                                            bool aWillClear) {
   if (AlreadyShutDown()) {
     gfxCriticalError() << "Attempt to render into a Canvas2d after shutdown.";
     SetErrorState();
     return false;
   }
 
   if (mTarget) {
     return true;
@@ -1253,17 +1250,18 @@ bool CanvasRenderingContext2D::EnsureTar
     SetErrorState();
     return false;
   }
 
   MOZ_ASSERT(newTarget);
   MOZ_ASSERT(newProvider);
 
   bool needsClear = !canDiscardContent;
-  if (newTarget->GetBackendType() == gfx::BackendType::SKIA && (needsClear || !aWillClear)) {
+  if (newTarget->GetBackendType() == gfx::BackendType::SKIA &&
+      (needsClear || !aWillClear)) {
     // Skia expects the unused X channel to contains 0xFF even for opaque
     // operations so we can't skip clearing in that case, even if we are going
     // to cover the entire canvas in the next drawing operation.
     newTarget->ClearRect(canvasRect);
     needsClear = false;
   }
 
   // Try to copy data from the previous buffer provider if there is one.
@@ -1367,18 +1365,20 @@ bool CanvasRenderingContext2D::TryShared
        mBufferProvider->GetType() == LayersBackend::LAYERS_WR)) {
     // we are already using a shared buffer provider, we are allocating a new
     // one because the current one failed so let's just fall back to the basic
     // provider.
     return false;
   }
 
 #ifdef XP_WIN
-  // Bug 1285271 - Disable shared buffer provider on Windows with D2D due to instability
-  if (gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() == BackendType::DIRECT2D1_1) {
+  // Bug 1285271 - Disable shared buffer provider on Windows with D2D due to
+  // instability
+  if (gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() ==
+      BackendType::DIRECT2D1_1) {
     return false;
   }
 #endif
 
   RefPtr<LayerManager> layerManager =
       LayerManagerFromCanvasElement(mCanvasElement);
 
   if (!layerManager) {
@@ -1404,16 +1404,24 @@ bool CanvasRenderingContext2D::TryBasicT
     RefPtr<gfx::DrawTarget>& aOutDT,
     RefPtr<layers::PersistentBufferProvider>& aOutProvider) {
   aOutDT = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(
       GetSize(), GetSurfaceFormat());
   if (!aOutDT) {
     return false;
   }
 
+  // See Bug 1524554 - this forces DT initialization.
+  aOutDT->ClearRect(gfx::Rect());
+
+  if (!aOutDT->IsValid()) {
+    aOutDT = nullptr;
+    return false;
+  }
+
   aOutProvider = new PersistentBufferProviderBasic(aOutDT);
   return true;
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight) {
   // Zero sized surfaces can cause problems.
   mZero = false;
@@ -4313,18 +4321,18 @@ void CanvasRenderingContext2D::DrawImage
 
     if (mCanvasElement) {
       CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement, res.mPrincipal,
                                             res.mIsWriteOnly, res.mCORSUsed);
     }
 
     if (res.mSourceSurface) {
       if (res.mImageRequest) {
-        CanvasImageCache::NotifyDrawImage(
-            element, mCanvasElement, res.mSourceSurface, imgSize);
+        CanvasImageCache::NotifyDrawImage(element, mCanvasElement,
+                                          res.mSourceSurface, imgSize);
       }
       srcSurf = res.mSourceSurface;
     } else {
       drawInfo = res.mDrawInfo;
     }
   }
 
   if (aOptional_argc == 0) {