Bug 787623. Call MarkContextClean immediately if we're not going to receive a DidTransactionCallback. r=joedrew,a=lsblakk
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 05 Sep 2012 22:28:23 +1200
changeset 104761 1c1b707222c9519780b3b62078aeb1624cf649e9
parent 104760 7220ec7a1dc61c513d618016920e887744ee3868
child 104762 5a0a98d11dbee38bcc2b419af03503347b6185d6
push id1401
push userrocallahan@mozilla.com
push dateWed, 12 Sep 2012 23:24:36 +0000
treeherdermozilla-beta@1c1b707222c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoedrew, lsblakk
bugs787623
milestone16.0
Bug 787623. Call MarkContextClean immediately if we're not going to receive a DidTransactionCallback. r=joedrew,a=lsblakk
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
layout/reftests/canvas/empty-transaction-1-ref.html
layout/reftests/canvas/empty-transaction-1.html
layout/reftests/canvas/reftest.list
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -4315,32 +4315,38 @@ static PRUint8 g2DContextLayerUserData;
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
                                            LayerManager *aManager)
 {
     // If we don't have anything to draw, don't bother.
     if (!mValid || !mSurface || mSurface->CairoStatus() || !mThebes ||
         !mSurfaceCreated) {
-         return nsnull;
+        // No DidTransactionCallback will be received, so mark the context clean
+        // now so future invalidations will be dispatched.
+        MarkContextClean();
+        return nsnull;
     }
 
     if (!mResetLayer && aOldLayer) {
         CanvasRenderingContext2DUserData* userData =
             static_cast<CanvasRenderingContext2DUserData*>(
                     aOldLayer->GetUserData(&g2DContextLayerUserData));
         if (userData && userData->IsForContext(this)) {
             NS_ADDREF(aOldLayer);
             return aOldLayer;
         }
     }
 
     nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
     if (!canvasLayer) {
         NS_WARNING("CreateCanvasLayer returned null!");
+        // No DidTransactionCallback will be received, so mark the context clean
+        // now so future invalidations will be dispatched.
+        MarkContextClean();
         return nsnull;
     }
     CanvasRenderingContext2DUserData *userData = nsnull;
     if (aBuilder->IsPaintingToWindow()) {
       // Make the layer tell us whenever a transaction finishes (including
       // the current transaction), so we can clear our invalidation state and
       // start invalidating again. We need to do this for the layer that is
       // being painted to a window (there shouldn't be more than one at a time,
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -4605,16 +4605,19 @@ nsCanvasRenderingContext2DAzure::SetMozI
 static PRUint8 g2DContextLayerUserData;
 
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
                                            LayerManager *aManager)
 {
   if (!mValid) {
+    // No DidTransactionCallback will be received, so mark the context clean
+    // now so future invalidations will be dispatched.
+    MarkContextClean();
     return nsnull;
   }
 
   if (mTarget) {
     mTarget->Flush();
   }
 
   if (!mResetLayer && aOldLayer) {
@@ -4625,16 +4628,19 @@ nsCanvasRenderingContext2DAzure::GetCanv
       NS_ADDREF(aOldLayer);
       return aOldLayer;
     }
   }
 
   nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
   if (!canvasLayer) {
     NS_WARNING("CreateCanvasLayer returned null!");
+    // No DidTransactionCallback will be received, so mark the context clean
+    // now so future invalidations will be dispatched.
+    MarkContextClean();
     return nsnull;
   }
   CanvasRenderingContext2DUserDataAzure *userData = nsnull;
   if (aBuilder->IsPaintingToWindow()) {
     // Make the layer tell us whenever a transaction finishes (including
     // the current transaction), so we can clear our invalidation state and
     // start invalidating again. We need to do this for the layer that is
     // being painted to a window (there shouldn't be more than one at a time,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/empty-transaction-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<div style="background:black; width:100px; height:100px;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/empty-transaction-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<body>
+<canvas style="display:block" id="c" width="100" height="100"></canvas>
+<script>
+var ctx = document.getElementById("c").getContext("2d");
+function doTest() {
+  document.documentElement.removeAttribute("class");
+  ctx.fillRect(0, 0, 100, 100);
+}
+window.addEventListener("MozReftestInvalidate", doTest, false);
+</script>
+</body>
+</html>
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -1,11 +1,13 @@
 == default-size.html default-size-ref.html
 == size-1.html size-1-ref.html
 
+== empty-transaction-1.html empty-transaction-1-ref.html
+
 == image-rendering-test.html image-rendering-ref.html
 == image-shadow.html image-shadow-ref.html
 
 asserts-if(cocoaWidget,0-2) == size-change-1.html size-change-1-ref.html
 
 != text-ltr-left.html text-blank.html
 != text-ltr-right.html text-blank.html
 != text-rtl-left.html text-blank.html