Bug 518959: Only repaint dirty parts, r=stuart, r=mfinkle

This commit is contained in:
Benjamin Stover 2009-10-05 23:14:57 -04:00
Родитель 585f42c11e
Коммит 5879d6272c
1 изменённых файлов: 29 добавлений и 30 удалений

Просмотреть файл

@ -92,10 +92,10 @@
const kXHTMLNamespaceURI = "http://www.w3.org/1999/xhtml"; const kXHTMLNamespaceURI = "http://www.w3.org/1999/xhtml";
// base-2 exponent for width, height of a single tile. // base-2 exponent for width, height of a single tile.
const kTileExponentWidth = 7; const kTileExponentWidth = 9;
const kTileExponentHeight = 7; const kTileExponentHeight = 9;
const kTileWidth = Math.pow(2, kTileExponentWidth); // 2^7 = 128 const kTileWidth = Math.pow(2, kTileExponentWidth); // 2^9 = 512
const kTileHeight = Math.pow(2, kTileExponentHeight); // 2^7 = 128 const kTileHeight = Math.pow(2, kTileExponentHeight); // 2^9 = 512
const kTileLazyRoundTimeCap = 500; // millis const kTileLazyRoundTimeCap = 500; // millis
const kInitialCacheCapacity = 200; const kInitialCacheCapacity = 200;
@ -179,10 +179,10 @@ TileManager.prototype = {
else else
criticalIsDirty = true; criticalIsDirty = true;
// XXX we may want to pass rect through to make markDirty only mark the let intersection = tile.boundRect.intersect(rects[i]);
// intersection of tile's boundRect with rect dirty (e.g. if we have big if (intersection) {
// tiles) tile.markDirty(intersection);
tile.markDirty(); }
if (crawler) if (crawler)
crawler.enqueue(tile.i, tile.j); crawler.enqueue(tile.i, tile.j);
@ -346,8 +346,21 @@ TileManager.prototype = {
}, },
_renderTile: function _renderTile(tile) { _renderTile: function _renderTile(tile) {
if (tile.isDirty()) if (tile.isDirty()) {
/*
let ctx = tile._canvas.getContext("2d");
ctx.save();
ctx.fillStyle = "rgba(0,255,0,.5)";
ctx.translate(-tile.boundRect.left, -tile.boundRect.top);
ctx.fillRect(tile._dirtyTileCanvasRect.left, tile._dirtyTileCanvasRect.top,
tile._dirtyTileCanvasRect.width, tile._dirtyTileCanvasRect.height);
ctx.restore();
window.setTimeout(function(bv) {
tile.render(bv);
}, 1000, this._browserView);
*/
tile.render(this._browserView); tile.render(this._browserView);
}
}, },
_appendTileSafe: function _appendTileSafe(tile) { _appendTileSafe: function _appendTileSafe(tile) {
@ -472,7 +485,6 @@ TileManager.TileCache.prototype = {
lookup: function lookup(i, j) { lookup: function lookup(i, j) {
let tile = null; let tile = null;
if (this._tileMap[i]) if (this._tileMap[i])
tile = this._tileMap[i][j] || null; tile = this._tileMap[i][j] || null;
@ -511,8 +523,7 @@ TileManager.TileCache.prototype = {
}, },
inBounds: function inBounds(i, j) { inBounds: function inBounds(i, j) {
return (0 <= i && 0 <= j return (0 <= i && 0 <= j && i <= this.iBound && j <= this.jBound);
&& i <= this.iBound && j <= this.jBound);
}, },
sortEvictionQueue: function sortEvictionQueue(cmp) { sortEvictionQueue: function sortEvictionQueue(cmp) {
@ -541,7 +552,6 @@ TileManager.TileCache.prototype = {
return null; return null;
let tile = this.lookup(i, j); let tile = this.lookup(i, j);
if (!tile && create) { if (!tile && create) {
tile = this._createTile(i, j, evictionGuard); tile = this._createTile(i, j, evictionGuard);
if (tile) tile.markDirty(); if (tile) tile.markDirty();
@ -625,7 +635,6 @@ TileManager.TileCache.prototype = {
this._tileMap[i] = []; this._tileMap[i] = [];
let tile = null; let tile = null;
if (this._tilePool.length < this._capacity) { // either capacity is if (this._tilePool.length < this._capacity) { // either capacity is
tile = new TileManager.Tile(i, j); // infinite, or we have tile = new TileManager.Tile(i, j); // infinite, or we have
this._tileMap[i][j] = tile; // room to allocate more this._tileMap[i][j] = tile; // room to allocate more
@ -659,7 +668,6 @@ TileManager.Tile = function Tile(i, j) {
}; };
TileManager.Tile.prototype = { TileManager.Tile.prototype = {
init: function init(i, j) { init: function init(i, j) {
if (!this.boundRect) if (!this.boundRect)
this.boundRect = new wsRect(i * kTileWidth, j * kTileHeight, kTileWidth, kTileHeight); this.boundRect = new wsRect(i * kTileWidth, j * kTileHeight, kTileWidth, kTileHeight);
@ -703,25 +711,20 @@ TileManager.Tile.prototype = {
*/ */
markDirty: function markDirty(dirtyRect) { markDirty: function markDirty(dirtyRect) {
if (!dirtyRect) { if (!dirtyRect) {
if (!this._dirtyTileCanvasRect) if (!this._dirtyTileCanvasRect)
this._dirtyTileCanvasRect = this.boundRect.clone(); this._dirtyTileCanvasRect = this.boundRect.clone();
else else
this._dirtyTileCanvasRect.copyFrom(this.boundRect); this._dirtyTileCanvasRect.copyFrom(this.boundRect);
} else {
} else { // XXX this case is not very well-tested
if (!this._dirtyTileCanvasRect) if (!this._dirtyTileCanvasRect)
this._dirtyTileCanvasRect = dirtyRect.intersect(this.boundRect); this._dirtyTileCanvasRect = dirtyRect.intersect(this.boundRect).round();
else if (dirtyRect.intersects(this.boundRect)) else if (dirtyRect.intersects(this.boundRect))
this._dirtyTileCanvasRect.expandToContain(dirtyRect.intersect(this.boundRect)); this._dirtyTileCanvasRect.expandToContain(dirtyRect.intersect(this.boundRect)).round();
} }
// XXX if, after the above, the dirty rectangle takes up a large enough // XXX if, after the above, the dirty rectangle takes up a large enough
// portion of the boundRect, we should probably just mark the entire tile // portion of the boundRect, we should probably just mark the entire tile
// dirty and fastpath for future calls. // dirty and fastpath for future calls.
if (this._dirtyTileCanvasRect) if (this._dirtyTileCanvasRect)
this._dirtyTileCanvas = true; this._dirtyTileCanvas = true;
}, },
@ -745,21 +748,17 @@ TileManager.Tile.prototype = {
this.markDirty(); this.markDirty();
let rect = this._dirtyTileCanvasRect; let rect = this._dirtyTileCanvasRect;
let x = rect.left - this.boundRect.left; let x = rect.left - this.boundRect.left;
let y = rect.top - this.boundRect.top; let y = rect.top - this.boundRect.top;
browserView.viewportToBrowserRect(rect); browserView.viewportToBrowserRect(rect);
let sourceContent = browserView._contentWindow;
let ctx = this._canvas.getContext("2d"); let ctx = this._canvas.getContext("2d");
ctx.save(); ctx.save();
browserView.browserToViewportCanvasContext(ctx);
ctx.translate(x, y); ctx.translate(x, y);
browserView.browserToViewportCanvasContext(ctx);
ctx.drawWindow(sourceContent, ctx.drawWindow(browserView._contentWindow,
rect.left, rect.top, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top, rect.right - rect.left, rect.bottom - rect.top,
"white", "white",