Video cell cache tweaks

This commit is contained in:
Jeff Parsons 2015-09-22 16:01:05 -07:00
commit ea53491a76

View file

@ -4964,27 +4964,28 @@ Video.prototype.setPixel = function(imageData, x, y, rgb)
}; };
/** /**
* initCellCache(fNew) * initCellCache()
* *
* Invalidates the contents of our internal cell cache. * Initializes the contents of our internal cell cache.
*
* TODO: Consider changing this to a cache of RGB values, so that when the buffer is merely being color-cycled,
* we don't have to update the entire screen. This will also allow invalidateScreen() to honor the fModified flag,
* bypassing initCellCache() when it is false.
* *
* @this {Video} * @this {Video}
* @param {boolean} [fNew] is true to reallocate/resize the cell cache; in any case, it's still reinitialized
*/ */
Video.prototype.initCellCache = function(fNew) Video.prototype.initCellCache = function()
{ {
this.cBlinkVisible = -1; // invalidate the visible blinking character count, to force updateScreen() to recount this.cBlinkVisible = -1; // invalidate the visible blinking character count, to force updateScreen() to recount
this.fCellCacheValid = false; this.fCellCacheValid = false;
if (fNew) { var nCells = this.nCellCache;
var nCells = this.nCellCache; if (this.aCellCache === undefined || this.aCellCache.length != nCells) {
if (this.aCellCache === undefined || this.aCellCache.length != nCells) { this.aCellCache = new Array(nCells);
this.aCellCache = new Array(nCells);
}
} }
}; };
/** /**
* invalidateScreen(fNew) * invalidateScreen(fModified)
* *
* Ensure that the next updateScreen() will update every cell; intended for situations where the entire screen needs * Ensure that the next updateScreen() will update every cell; intended for situations where the entire screen needs
* to be redrawn, even though the underlying data in the video buffer has not changed (and therefore cleanMemory() will * to be redrawn, even though the underlying data in the video buffer has not changed (and therefore cleanMemory() will
@ -4993,12 +4994,12 @@ Video.prototype.initCellCache = function(fNew)
* For example, when the palette is being cycled, the screen is being panned, the page is being flipped, etc. * For example, when the palette is being cycled, the screen is being panned, the page is being flipped, etc.
* *
* @this {Video} * @this {Video}
* @param {boolean} [fNew] is passed through to initCellCache; typically true when a new mode has been set. * @param {boolean} [fModified] (true if the buffer may have been modified, false if only color(s) may have changed)
*/ */
Video.prototype.invalidateScreen = function(fNew) Video.prototype.invalidateScreen = function(fModified)
{ {
this.fRGBValid = false; if (!fModified) this.fRGBValid = false;
this.initCellCache(fNew); this.initCellCache();
}; };
/** /**
@ -5183,7 +5184,7 @@ Video.prototype.updateScreen = function(fForce)
if (!fEnabled && !fForce) return; if (!fEnabled && !fForce) return;
if (fForce) { if (fForce) {
this.initCellCache(true); this.initCellCache();
} }
else { else {
/* /*
@ -5667,22 +5668,8 @@ Video.prototype.updateScreenGraphicsVGA = function(addrBuffer, addrScreen, addrS
if (iPixelFirst) { if (iPixelFirst) {
/* /*
* Notice that we're not using the cell cache when panning is active, because the cached cell data no * TODO: Implement support for 8bpp panning
* longer aligns with the data we're pulling out of the video buffer, and it's not clear that the effort
* to realign the data and make a valid cache comparison would save enough work to make it worthwhile.
*/ */
if (!x) {
data <<= iPixelFirst;
nPixels -= iPixelFirst;
/*
* This is as good a place as any to invalidate the cell cache when panning is active; this ensures
* we don't rely on stale cache contents once panning stops.
*/
this.fCellCacheValid = false;
} else {
iPixel = this.nCols - x;
if (nPixels > iPixel) nPixels = iPixel;
}
} else { } else {
this.assert(iCell < this.aCellCache.length); this.assert(iCell < this.aCellCache.length);
if (this.fCellCacheValid && data === this.aCellCache[iCell]) { if (this.fCellCacheValid && data === this.aCellCache[iCell]) {
@ -5697,9 +5684,8 @@ Video.prototype.updateScreenGraphicsVGA = function(addrBuffer, addrScreen, addrS
if (nPixels) { if (nPixels) {
if (x < xDirty) xDirty = x; if (x < xDirty) xDirty = x;
for (iPixel = 0; iPixel < nPixels; iPixel++) { for (iPixel = 0; iPixel < nPixels; iPixel++) {
var bPixel = data & 0xff; this.setPixel(this.imageScreenBuffer, x++, y, aPixelColors[data & 0xff]);
this.setPixel(this.imageScreenBuffer, x++, y, aPixelColors[bPixel]); data >>= 8;
data >>>= 8;
} }
if (x > xMaxDirty) xMaxDirty = x; if (x > xMaxDirty) xMaxDirty = x;
if (y < yDirty) yDirty = y; if (y < yDirty) yDirty = y;
@ -6004,7 +5990,7 @@ Video.prototype.outATC = function(port, bOut, addrFrom)
this.printMessageIO(port, bOut, addrFrom, "ATC." + card.asATCRegs[iReg]); this.printMessageIO(port, bOut, addrFrom, "ATC." + card.asATCRegs[iReg]);
} }
card.regATCData[iReg] = bOut; card.regATCData[iReg] = bOut;
this.invalidateScreen(); this.invalidateScreen(false);
} }
} }
} }
@ -6315,7 +6301,7 @@ Video.prototype.outDACData = function(port, bOut, addrFrom)
var dwNew = (dw & ~(0x3f << this.cardEGA.regDACShift)) | ((bOut & 0x3f) << this.cardEGA.regDACShift); var dwNew = (dw & ~(0x3f << this.cardEGA.regDACShift)) | ((bOut & 0x3f) << this.cardEGA.regDACShift);
if (dw !== dwNew) { if (dw !== dwNew) {
this.cardEGA.regDACData[this.cardEGA.regDACAddr] = dwNew; this.cardEGA.regDACData[this.cardEGA.regDACAddr] = dwNew;
this.invalidateScreen(); this.invalidateScreen(false);
} }
this.cardEGA.regDACShift += 6; this.cardEGA.regDACShift += 6;
if (this.cardEGA.regDACShift > 12) { if (this.cardEGA.regDACShift > 12) {
@ -6600,11 +6586,7 @@ Video.prototype.outCGAColor = function(port, bOut, addrFrom)
} }
if (this.cardColor.regColor !== bOut) { if (this.cardColor.regColor !== bOut) {
this.cardColor.regColor = bOut; this.cardColor.regColor = bOut;
/* this.invalidateScreen(false);
* When this color register changes, it can automatically change the appearance of any number of cells, so we make
* a special call to initCellCache() to invalidate every cell, forcing all cells to be redrawn on the next updateScreen().
*/
this.initCellCache();
} }
}; };