mirror of
https://github.com/boxgaming/qbjs.git
synced 2024-09-19 20:14:58 +00:00
implemented screen cache to improve performance of PSet-intensive programs
This commit is contained in:
parent
fce1e16005
commit
2bf17466d9
1 changed files with 52 additions and 40 deletions
92
qb.js
92
qb.js
|
@ -137,6 +137,7 @@ var QB = new function() {
|
|||
};
|
||||
|
||||
this.end = function() {
|
||||
_flushAllScreenCache();
|
||||
_runningFlag = false;
|
||||
};
|
||||
|
||||
|
@ -407,6 +408,7 @@ var QB = new function() {
|
|||
};
|
||||
|
||||
this.sub__Limit = async function(fps) {
|
||||
_flushAllScreenCache();
|
||||
await GX.sleep((1000 - (new Date() - _lastLimitTime))/fps);
|
||||
_lastLimitTime = new Date();
|
||||
};
|
||||
|
@ -414,6 +416,7 @@ var QB = new function() {
|
|||
this.autoLimit = async function() {
|
||||
var timeElapsed = new Date() - _lastLimitTime;
|
||||
if (timeElapsed > 1000) {
|
||||
_flushAllScreenCache();
|
||||
await GX.sleep(1);
|
||||
_lastLimitTime = new Date();
|
||||
}
|
||||
|
@ -524,7 +527,7 @@ var QB = new function() {
|
|||
// TODO: check the background opacity mode
|
||||
// Draw the text background
|
||||
var ctx = _images[_activeImage].ctx;
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = _bgColor.rgba();
|
||||
ctx.fillRect(x, y, QB.func__FontWidth(), QB.func__FontHeight());
|
||||
|
@ -625,8 +628,8 @@ var QB = new function() {
|
|||
sourceImage.lastX = sx1 + sw;
|
||||
sourceImage.lastY = sy2 + sh;
|
||||
|
||||
_flushScreenCache(_images[destImageId]);
|
||||
destImage.ctx.drawImage(sourceImage.canvas, sx1, sy1, sw, sh, dx1, dy1, dw, dh);
|
||||
_images[sourceImageId].dirty = true;
|
||||
}
|
||||
|
||||
function _rgb(r, g, b, a) {
|
||||
|
@ -899,7 +902,7 @@ var QB = new function() {
|
|||
}
|
||||
|
||||
ctx = _images[_activeImage].ctx;
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
ctx.beginPath();
|
||||
ctx.clearRect(0, 0, _width(), _height());
|
||||
//if (_screenMode == 1) { TODO: Finish implementing this.
|
||||
|
@ -933,23 +936,12 @@ var QB = new function() {
|
|||
}
|
||||
|
||||
this.sub_Color = function(x, y) {
|
||||
/*if (_screenMode == 1) { This code is fine.
|
||||
if (x == 0) { _bgColor = _rgb(0, 0, 0);
|
||||
} else if (x == 1) { _bgColor = _rgb(0, 0, 168);
|
||||
} else if (x == 2) { _bgColor = _rgb(0, 168, 0);
|
||||
} else if (x == 3) { _bgColor = _rgb(0, 168, 168); }
|
||||
ctx = _images[_activeImage].ctx;
|
||||
ctx.fillStyle = _bgColor.rgba();
|
||||
ctx.beginPath();
|
||||
ctx.fillRect(0, 0, _width(), _height());
|
||||
} else {*/
|
||||
if (x != undefined) {
|
||||
_fgColor = _color(x);
|
||||
}
|
||||
if (y != undefined) {
|
||||
_bgColor = _color(y);
|
||||
}
|
||||
//}
|
||||
};
|
||||
|
||||
this.func_Command = function() {
|
||||
|
@ -1059,7 +1051,7 @@ var QB = new function() {
|
|||
["H",Math.PI*(7/4),Math.sqrt(2)]];
|
||||
|
||||
// Screen variables.
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
var screen = _images[_activeImage];
|
||||
var ctx = screen.ctx;
|
||||
|
||||
|
@ -1342,6 +1334,8 @@ var QB = new function() {
|
|||
var str = "";
|
||||
_inputMode = true;
|
||||
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
|
||||
if (prompt != undefined) {
|
||||
await QB.sub_Print([prompt, QB.PREVENT_NEWLINE]);
|
||||
}
|
||||
|
@ -1391,7 +1385,6 @@ var QB = new function() {
|
|||
}
|
||||
}
|
||||
_inputMode = false;
|
||||
_images[_activeImage].dirty = true;
|
||||
}
|
||||
|
||||
this.sub_InputFromFile = async function(fh, returnValues) {
|
||||
|
@ -1492,7 +1485,7 @@ var QB = new function() {
|
|||
|
||||
var screen = _images[_activeImage];
|
||||
var ctx = screen.ctx;
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(screen);
|
||||
|
||||
if (color == undefined) {
|
||||
color = _fgColor;
|
||||
|
@ -1557,17 +1550,10 @@ var QB = new function() {
|
|||
|
||||
this.sub_Line = function(sstep, sx, sy, estep, ex, ey, color, style, pattern) {
|
||||
var screen = _images[_activeImage];
|
||||
//var ctx = screen.ctx;
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
|
||||
if (color == undefined) {
|
||||
color = _fgColor;
|
||||
/*if (style == "BF") {
|
||||
color = _bgColor;
|
||||
}
|
||||
else {
|
||||
color = _fgColor;
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
color = _color(color);
|
||||
|
@ -1811,7 +1797,8 @@ var QB = new function() {
|
|||
|
||||
this.sub_Paint = function(sstep, startX, startY, fillColor, borderColor) {
|
||||
// See: http://www.williammalone.com/articles/html5-canvas-javascript-paint-bucket-tool/
|
||||
_images[_activeImage].dirty = true;
|
||||
// TODO: this method should probably utilize the same screen cache as PSet
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
var screen = _images[_activeImage];
|
||||
var ctx = screen.ctx;
|
||||
var data = ctx.getImageData(0, 0, screen.canvas.width, screen.canvas.height).data;
|
||||
|
@ -1915,18 +1902,16 @@ var QB = new function() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (screen.dirty != false) {
|
||||
if (!screen.cached) {
|
||||
var ctx = screen.ctx;
|
||||
screen.data = ctx.getImageData(0, 0, screen.canvas.width, screen.canvas.height).data;
|
||||
screen.dirty = false;
|
||||
screen.imgdata = ctx.getImageData(0, 0, screen.canvas.width, screen.canvas.height);
|
||||
screen.cached = true;
|
||||
}
|
||||
//var data = ctx.getImageData(x, y, 1, 1).data;
|
||||
//ret = QB.func__RGBA(data[0],data[1],data[2],data[3]);
|
||||
var pixelIndex = (y * screen.canvas.width + x) * 4;
|
||||
ret = _rgb(screen.data[pixelIndex],
|
||||
screen.data[pixelIndex + 1],
|
||||
screen.data[pixelIndex + 2],
|
||||
screen.data[pixelIndex + 3]);
|
||||
ret = _rgb(screen.imgdata.data[pixelIndex],
|
||||
screen.imgdata.data[pixelIndex + 1],
|
||||
screen.imgdata.data[pixelIndex + 2],
|
||||
screen.imgdata.data[pixelIndex + 3]);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -2018,7 +2003,8 @@ var QB = new function() {
|
|||
args = [""];
|
||||
}
|
||||
|
||||
_images[_activeImage].dirty = true;
|
||||
_flushScreenCache(_images[_activeImage]);
|
||||
|
||||
var ctx = _images[_activeImage].ctx;
|
||||
var preventNewline = (args[args.length-1] == QB.PREVENT_NEWLINE || args[args.length-1] == QB.COLUMN_ADVANCE);
|
||||
|
||||
|
@ -2095,9 +2081,11 @@ var QB = new function() {
|
|||
}
|
||||
|
||||
this.sub_PSet = function(sstep, x, y, color) {
|
||||
_images[_activeImage].dirty = true;
|
||||
var screen = _images[_activeImage];
|
||||
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
|
||||
if (color == undefined) {
|
||||
color = _fgColor;
|
||||
}
|
||||
|
@ -2122,14 +2110,38 @@ var QB = new function() {
|
|||
screen.lastX = x;
|
||||
screen.lastY = y;
|
||||
|
||||
if (!screen.cached) {
|
||||
var ctx = screen.ctx;
|
||||
ctx.fillStyle = color.rgba();
|
||||
ctx.beginPath();
|
||||
ctx.fillRect(x, y, 1, 1);
|
||||
screen.imgdata = ctx.getImageData(0, 0, screen.canvas.width, screen.canvas.height);
|
||||
screen.cached = true;
|
||||
}
|
||||
var pixelIndex = (y * screen.canvas.width + x) * 4;
|
||||
screen.imgdata.data[pixelIndex] = color.r;
|
||||
screen.imgdata.data[pixelIndex + 1] = color.g;
|
||||
screen.imgdata.data[pixelIndex + 2] = color.b;
|
||||
screen.imgdata.data[pixelIndex + 3] = color.a * 255;
|
||||
|
||||
_strokeDrawColor = _color(color);
|
||||
};
|
||||
|
||||
function _flushScreenCache(screen) {
|
||||
if (screen.cached) {
|
||||
var ctx = screen.ctx;
|
||||
ctx.putImageData(screen.imgdata, 0, 0);
|
||||
screen.imgdata = undefined;
|
||||
screen.cached = false;
|
||||
}
|
||||
}
|
||||
|
||||
function _flushAllScreenCache() {
|
||||
// TODO: this is brute force - fix it
|
||||
for (var i=0; i < _nextImageId; i++) {
|
||||
if (_images[i]) {
|
||||
_flushScreenCache(_images[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.sub_Get = function(fhi, position, type, valueObj) {
|
||||
if (!_fileHandles[fhi]) {
|
||||
throw new Error("Invalid file handle");
|
||||
|
|
Loading…
Reference in a new issue