Bug 599512 Partial black thumbnails on viewports with width != 800 r=mfinkle
authorBenjamin Stover <bstover@mozilla.com>
Fri, 24 Sep 2010 17:41:10 -0700
changeset 66712 bc15d66ebfe171617793cb4765acb2d0ed8f3a06
parent 66711 5d73a4d386cb4238d3092195f95ae62470f2b3f2
child 66713 bc8c319acdcced5cad29630abe0bdcee5dd0555b
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs599512
Bug 599512 Partial black thumbnails on viewports with width != 800 r=mfinkle
mobile/chrome/content/browser.js
mobile/chrome/content/content.js
mobile/chrome/content/tabs.xml
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -1015,18 +1015,21 @@ var Browser = {
     let json = aMessage.json;
     let browser = aMessage.target;
 
     switch (aMessage.name) {
       case "Browser:ViewportMetadata":
         let tab = Browser.getTabForBrowser(browser);
         // Some browser such as iframes loaded dynamically into the chrome UI
         // does not have any assigned tab
-        if (tab)
+        if (tab) {
           tab.updateViewportMetadata(json);
+          if (!this.isLoading())
+            tab.updateThumbnail();
+        }
         break;
 
       case "Browser:FormSubmit":
         browser.lastLocation = null;
         break;
 
       case "Browser:ZoomToPoint:Return":
         // JSON-ified rect needs to be recreated so the methods exist
@@ -2354,17 +2357,16 @@ Tab.prototype = {
       }
 
       browser.setWindowSize(w, h);
     }
   },
 
   startLoading: function startLoading() {
     if (this._loading) throw "Already Loading!";
-
     this._loading = true;
   },
 
   endLoading: function endLoading() {
     if (!this._loading) throw "Not Loading!";
     this._loading = false;
   },
 
@@ -2497,23 +2499,30 @@ Tab.prototype = {
     return this._browser.getBoundingClientRect().width / browserW;
   },
 
   get allowZoom() {
     return this.metadata.allowZoom;
   },
 
   updateThumbnail: function updateThumbnail() {
-    if (!this._browser)
+    let browser = this._browser;
+
+    // Do not repaint thumbnail if we already painted for this load. Bad things
+    // happen when we do async canvas draws in quick succession.
+    if (!browser || this._lastThumbnailWindow == browser.contentWindowId)
       return;
 
-    // XXX: We don't know the size of the browser at this time and we can't fallback
-    // to contentWindow.innerWidth and .innerHeight. The viewport meta data is not
-    // even set yet. So fallback to something sane for now.
-    this._chromeTab.updateThumbnail(this._browser, 800, 500);
+    // Do not try to paint thumbnails if contentWindowWidth/Height have not been
+    // set yet. This also blows up for async canvas draws.
+    if (!browser.contentWindowWidth || !browser.contentWindowHeight)
+      return;
+
+    this._lastThumbnailWindow = browser.contentWindowId;
+    this._chromeTab.updateThumbnail(browser, browser.contentWindowWidth, browser.contentWindowHeight);
   },
 
   toString: function() {
     return "[Tab " + (this._browser ? this._browser.currentURI.spec : "(no browser)") + "]";
   }
 };
 
 // Helper used to hide IPC / non-IPC differences for rendering to a canvas
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -482,32 +482,34 @@ let ViewportHandler = {
   init: function init() {
     addEventListener("DOMWindowCreated", this, false);
     addEventListener("DOMMetaAdded", this, false);
     addEventListener("DOMContentLoaded", this, false);
     addEventListener("pageshow", this, false);
   },
 
   handleEvent: function handleEvent(aEvent) {
+    let target = aEvent.originalTarget;
+    let isRootDocument = (target == content.document || target.ownerDocument == content.document);
+    if (!isRootDocument)
+      return;
+
     switch (aEvent.type) {
       case "DOMWindowCreated":
         this.resetMetadata();
         break;
 
       case "DOMMetaAdded":
-        let target = aEvent.originalTarget;
-        let isRootDocument = (target.ownerDocument == content.document);
-        if (isRootDocument && target.name == "viewport")
+        if (target.name == "viewport")
           this.updateMetadata();
         break;
 
       case "DOMContentLoaded":
       case "pageshow":
-        if (!this.metadata)
-          this.updateMetadata();
+        this.updateMetadata();
         break;
     }
   },
 
   resetMetadata: function resetMetadata() {
     this.metadata = null;
     sendAsyncMessage("Browser:ViewportMetadata", null);
   },
--- a/mobile/chrome/content/tabs.xml
+++ b/mobile/chrome/content/tabs.xml
@@ -42,20 +42,24 @@
         <parameter name="browser"/>
         <parameter name="width"/>
         <parameter name="height"/>
         <body>
           <![CDATA[
             const tabWidth = 106;
             const tabHeight = 64;
 
+            let ratio = tabHeight / tabWidth;
+            height = width * ratio;
+
             let canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
             let renderer = rendererFactory(browser, canvas)
             renderer.drawContent(function(ctx, callback) {
-              ctx.clearRect(0, 0, tabWidth, tabHeight);
+              ctx.fillStyle = "white";
+              ctx.fillRect(0, 0, tabWidth, tabHeight);
               ctx.save();
               ctx.scale(tabWidth / width, tabHeight / height);
               callback(browser, 0, 0, width, height, "white");
               ctx.restore();
             });
           ]]>
         </body>
       </method>