Bug 588452 - Don't render to zoom snapshot canvas before prior render finishes [r=stechz]
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 18 Aug 2010 19:30:42 -0700
changeset 1808 fa32126e5d30c2ebb5b8150a4a6b5fda8f7df57f
parent 1807 e0dfff13f53c5ddbe916fd0124925e6b51e9e8b9
child 1809 c195d2ca37e39c4ed788277c573c7c0b25c38aff
push id1613
push usermbrubeck@mozilla.com
push dateThu, 19 Aug 2010 02:31:34 +0000
reviewersstechz
bugs588452
Bug 588452 - Don't render to zoom snapshot canvas before prior render finishes [r=stechz]
chrome/content/AnimatedZoom.js
--- a/chrome/content/AnimatedZoom.js
+++ b/chrome/content/AnimatedZoom.js
@@ -46,49 +46,55 @@ let Cu = Components.utils;
 /**
  * Responsible for zooming in to a given view rectangle
  * @param aBrowserView BrowserView instance
  * @param aZoomRect Optional. Zoom rectangle to be configured
  */
 function AnimatedZoom(aBrowserView) {
   this.bv = aBrowserView;
 
+  this.snapshot = AnimatedZoom.createCanvas();
+  if (this.snapshot.pending_render)
+    return;
+
   // Render a snapshot of the viewport contents around the visible rect
   let [w, h] = this.bv.getViewportDimensions();
   let viewportRect = new Rect(0, 0, w, h);
   this.zoomFrom = this.bv.getVisibleRect().translateInside(viewportRect);
 
   // try to cover twice the size of the current visible rect
   this.snapshotRect = this.bv.getVisibleRect().inflate(2);
 
   // sanitize the snapshot rectangle to fit inside viewport
   this.snapshotRect.translateInside(viewportRect).restrictTo(viewportRect).expandToIntegers();
-
-  this.snapshot = AnimatedZoom.createCanvas();
   this.snapshotRect.width = Math.min(this.snapshotRect.width, this.snapshot.width);
   this.snapshotRect.height = Math.min(this.snapshotRect.height, this.snapshot.height);
 
   let snapshotCtx = this.snapshot.MozGetIPCContext("2d")
   snapshotCtx.clearRect(0, 0, this.snapshotRect.width, this.snapshotRect.height);
   this.bv.renderToCanvas(this.snapshot, this.snapshotRect.width, this.snapshotRect.height, this.snapshotRect.clone());
 
   let remote = !this.bv.getBrowser().contentWindow;
   if (remote) {
     this.canvasReady = false;
     this.snapshot.addEventListener("MozAsyncCanvasRender", this, false);
+    this.snapshot.pending_render = true;
   } else {
     this.canvasReady = true;
     this.startAnimation();
   }
 }
 
 AnimatedZoom.prototype.handleEvent = function(aEvent) {
   if (aEvent.type == "MozAsyncCanvasRender") {
-    this.snapshot.removeEventListener("MozAsyncCanvasRender", this, false);
-    if (aEvent.originalTarget == this.snapshot) {
+    let snapshot = aEvent.originalTarget;
+    snapshot.pending_render = false;
+    snapshot.removeEventListener("MozAsyncCanvasRender", this, false);
+
+    if (this.snapshot == snapshot) {
       this.canvasReady = true;
       this.startAnimation();
     }
   }
 };
 
 /** Creating a canvas element of width and height. */
 AnimatedZoom.createCanvas = function(aRemote) {
@@ -145,16 +151,19 @@ AnimatedZoom.prototype.startAnimation = 
     this.lastTime = 0;
   }
 };
 
 /** Updates the zoom to new rect. */
 AnimatedZoom.prototype.updateTo = function(nextRect) {
   this.zoomRect = nextRect;
 
+  if (this.snapshot.pending_render)
+    return;
+
   // prepare to draw to the zoom canvas
   let canvasRect = new Rect(0, 0, Elements.viewBuffer.width, Elements.viewBuffer.height);
   let ctx = Elements.viewBuffer.getContext("2d");
   ctx.save();
 
   // srcRect = area inside this.snapshot to copy from
   let srcRect = nextRect.intersect(this.snapshotRect);
   if (srcRect.isEmpty())