From 097020cf5a89a29ea4bc59a5650bbfd350f0af1c Mon Sep 17 00:00:00 2001 From: Frank Yan Date: Tue, 19 Feb 2013 13:56:48 -0800 Subject: [PATCH] Bug 836430 - [HiDPI] Store swipe animation snapshots in HiDPI on HiDPI hardware. r=felipe --- .../base/content/browser-gestureSupport.js | 73 +++++++++++++++---- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/browser/base/content/browser-gestureSupport.js b/browser/base/content/browser-gestureSupport.js index 4c2e31baced..71beda9e2e0 100644 --- a/browser/base/content/browser-gestureSupport.js +++ b/browser/base/content/browser-gestureSupport.js @@ -586,6 +586,7 @@ let gHistorySwipeAnimation = { this._maxSnapshots = this._getMaxSnapshots(); this._lastSwipeDir = ""; this._direction = "horizontal"; + this._scale = window.matchMedia("(resolution: 2dppx)").matches ? 2 : 1; // We only want to activate history swipe animations if we store snapshots. // If we don't store any, we handle horizontal swipes without animations. @@ -645,9 +646,9 @@ let gHistorySwipeAnimation = { this._canGoBack = this.canGoBack(); this._canGoForward = this.canGoForward(); if (this.active) { + this._addBoxes(); this._takeSnapshot(); this._installPrevAndNextSnapshots(); - this._addBoxes(); this._lastSwipeDir = ""; } } @@ -950,15 +951,15 @@ let gHistorySwipeAnimation = { let browser = gBrowser.selectedBrowser; let r = browser.getBoundingClientRect(); canvas = document.createElementNS("http://www.w3.org/1999/xhtml", - "canvas"); + "canvas"); canvas.mozOpaque = true; - canvas.width = r.width; - canvas.height = r.height; + canvas.width = r.width * this._scale; + canvas.height = r.height * this._scale; let ctx = canvas.getContext("2d"); - let zoom = browser.markupDocumentViewer.fullZoom; + let zoom = browser.markupDocumentViewer.fullZoom * this._scale; ctx.scale(zoom, zoom); ctx.drawWindow(browser.contentWindow, - 0, 0, r.width / zoom, r.height / zoom, "white", + 0, 0, canvas.width / zoom, canvas.height / zoom, "white", ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_ASYNC_DECODE_IMAGES | ctx.DRAWWINDOW_USE_WIDGET_LAYERS); @@ -1005,11 +1006,16 @@ let gHistorySwipeAnimation = { // Temporarily store the canvas as the compressed snapshot. // This avoids a blank page if the user swipes quickly // between pages before the compression could complete. - snapshots[currIndex] = aCanvas; + snapshots[currIndex] = { + image: aCanvas, + scale: this._scale + }; // Kick off snapshot compression. aCanvas.toBlob(function(aBlob) { - snapshots[currIndex] = aBlob; + if (snapshots[currIndex]) { + snapshots[currIndex].image = aBlob; + } }, "image/png" ); }, @@ -1060,6 +1066,7 @@ let gHistorySwipeAnimation = { while (arr.length > this._maxSnapshots) { let lastElem = arr[arr.length - 1]; + delete lastElem.browser.snapshots[lastElem.index].image; delete lastElem.browser.snapshots[lastElem.index]; arr.splice(-1, 1); } @@ -1097,6 +1104,31 @@ let gHistorySwipeAnimation = { } }, + /** + * Scales the background of a given box element (which uses a given snapshot + * as background) based on a given scale factor. + * @param aSnapshot + * The snapshot that is used as background of aBox. + * @param aScale + * The scale factor to use. + * @param aBox + * The box element that uses aSnapshot as background. + */ + _scaleSnapshot: function HSA__scaleSnapshot(aSnapshot, aScale, aBox) { + if (aSnapshot && aScale != 1 && aBox) { + if (aSnapshot instanceof HTMLCanvasElement) { + aBox.style.backgroundSize = + aSnapshot.width / aScale + "px " + aSnapshot.height / aScale + "px"; + } else { + // snapshot is instanceof HTMLImageElement + aSnapshot.addEventListener("load", function() { + aBox.style.backgroundSize = + aSnapshot.width / aScale + "px " + aSnapshot.height / aScale + "px"; + }); + } + } + }, + /** * Sets the snapshot of the current page to the snapshot passed as parameter, * or to the one previously stored for the current index in history if the @@ -1109,14 +1141,19 @@ let gHistorySwipeAnimation = { _installCurrentPageSnapshot: function HSA__installCurrentPageSnapshot(aCanvas) { let currSnapshot = aCanvas; + let scale = this._scale; if (!currSnapshot) { let snapshots = gBrowser.selectedBrowser.snapshots || {}; let currIndex = this._historyIndex; - if (currIndex in snapshots) - currSnapshot = this._convertToImg(snapshots[currIndex]); + if (currIndex in snapshots) { + currSnapshot = this._convertToImg(snapshots[currIndex].image); + scale = snapshots[currIndex].scale; + } } + this._scaleSnapshot(currSnapshot, scale, this._curBox ? this._curBox : + null); document.mozSetImageElement("historySwipeAnimationCurrentPageSnapshot", - currSnapshot); + currSnapshot); }, /** @@ -1129,15 +1166,21 @@ let gHistorySwipeAnimation = { let currIndex = this._historyIndex; let prevIndex = currIndex - 1; let prevSnapshot = null; - if (prevIndex in snapshots) - prevSnapshot = this._convertToImg(snapshots[prevIndex]); + if (prevIndex in snapshots) { + prevSnapshot = this._convertToImg(snapshots[prevIndex].image); + this._scaleSnapshot(prevSnapshot, snapshots[prevIndex].scale, + this._prevBox); + } document.mozSetImageElement("historySwipeAnimationPreviousPageSnapshot", prevSnapshot); let nextIndex = currIndex + 1; let nextSnapshot = null; - if (nextIndex in snapshots) - nextSnapshot = this._convertToImg(snapshots[nextIndex]); + if (nextIndex in snapshots) { + nextSnapshot = this._convertToImg(snapshots[nextIndex].image); + this._scaleSnapshot(nextSnapshot, snapshots[nextIndex].scale, + this._nextBox); + } document.mozSetImageElement("historySwipeAnimationNextPageSnapshot", nextSnapshot); },