diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 553e5d409e9..0749eab8509 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -155,6 +155,21 @@ var Strings = {}; }); }); +var MetadataProvider = { + getDrawMetadata: function getDrawMetadata() { + return BrowserApp.getDrawMetadata(); + }, + + paintingSuppressed: function paintingSuppressed() { + let browser = BrowserApp.selectedBrowser; + if (!browser) + return false; + let cwu = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + return cwu.paintingSuppressed; + } +}; + var BrowserApp = { _tabs: [], _selectedTab: null, @@ -169,7 +184,7 @@ var BrowserApp = { BrowserEventHandler.init(); ViewportHandler.init(); - getBridge().setDrawMetadataProvider(this.getDrawMetadata.bind(this)); + getBridge().setDrawMetadataProvider(MetadataProvider); Services.obs.addObserver(this, "Tab:Add", false); Services.obs.addObserver(this, "Tab:Load", false); diff --git a/widget/android/nsIAndroidBridge.idl b/widget/android/nsIAndroidBridge.idl index 7e2d837e52c..e3c860e18f1 100644 --- a/widget/android/nsIAndroidBridge.idl +++ b/widget/android/nsIAndroidBridge.idl @@ -1,8 +1,14 @@ #include "nsISupports.idl" -[scriptable, function, uuid(9feed1e5-bb90-4663-b70a-e03cb27a9e8b)] +[scriptable, uuid(38b5c83a-3e8d-45c2-8311-6e36bd5116c0)] interface nsIAndroidDrawMetadataProvider : nsISupports { AString getDrawMetadata(); + + /* + * Returns true if the presentation shell corresponding to the currently-viewed document is + * suppressing painting (which occurs during page transitions) and false otherwise. + */ + boolean paintingSuppressed(); }; [scriptable, uuid(7dd8441a-4f38-49b2-bd90-da69d02a96cf)] diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 63461edb20b..377788e1b65 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1168,6 +1168,22 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) if (gAndroidBounds.width <= 0 || gAndroidBounds.height <= 0) return; + /* + * Check to see whether the presentation shell corresponding to the document on the screen + * is suppressing painting. If it is, we bail out, as continuing would result in a mismatch + * between the content on the screen and the current viewport metrics. + */ + nsCOMPtr metadataProvider = + AndroidBridge::Bridge()->GetDrawMetadataProvider(); + + bool paintingSuppressed = false; + if (metadataProvider) { + metadataProvider->PaintingSuppressed(&paintingSuppressed); + } + if (paintingSuppressed) { + return; + } + AndroidGeckoSoftwareLayerClient &client = AndroidBridge::Bridge()->GetSoftwareLayerClient(); client.BeginDrawing(gAndroidBounds.width, gAndroidBounds.height); @@ -1207,11 +1223,8 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) DrawTo(targetSurface, ae->Rect()); } - { - nsCOMPtr metadataProvider = - AndroidBridge::Bridge()->GetDrawMetadataProvider(); - if (metadataProvider) - metadataProvider->GetDrawMetadata(metadata); + if (metadataProvider) { + metadataProvider->GetDrawMetadata(metadata); } } if (sHasDirectTexture) {