Remove support for non-HTML5 browsers.
Display API change: - getTile -> startTile (no longer returns a tile) - setSubTile -> subTile (drop img/tile first parameter) - putTile -> finishTile (no longer takes img/tile paramter) The Display tile logic uses canvas image data directly and caches/reuses a 16x16 imageData tile (for other sizes, the tile is create for each call). This gives a 30% speedup on Chrome 13 (and no significant change for Firefox 3.6/4.0). Other: - Remove rgbxImageFill and cmapImageFill routines. - Simplify constructor tests and just error if createImageData is not supported by canvas instead of . - Remove webkit canvas bug workaround that effects Chrome 7. Chrome 7 usage share is now less than 0.5 percent and the workaround is ugly. Drop the function wrapping in the constructor and the canvas flush() routine. - Remove support for getImageData (Opera 11+ now required) Update browser support list: - Chrome 8+ (really any except 7) - Firefox 3.6+ - Safari 4+ - Opera 11+ - IE9+ - iOS 4.2+
This commit is contained in:
parent
859fc7f18f
commit
490d471c53
|
@ -19,11 +19,9 @@ var that = {}, // Public API methods
|
|||
c_ctx = null,
|
||||
c_forceCanvas = false,
|
||||
|
||||
c_imageData, c_rgbxImage, c_cmapImage,
|
||||
|
||||
// Predefine function variables (jslint)
|
||||
imageDataCreate, imageDataGet, rgbxImageData, cmapImageData,
|
||||
rgbxImageFill, cmapImageFill, setFillColor, rescale, flush,
|
||||
imageDataGet, rgbxImageData, cmapImageData,
|
||||
setFillColor, rescale,
|
||||
|
||||
// The full frame buffer (logical canvas) size
|
||||
fb_width = 0,
|
||||
|
@ -33,9 +31,11 @@ var that = {}, // Public API methods
|
|||
cleanRect = {'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1},
|
||||
|
||||
c_prevStyle = "",
|
||||
tile = null,
|
||||
tile16x16 = null,
|
||||
tile_x = 0,
|
||||
tile_y = 0;
|
||||
|
||||
c_webkit_bug = false,
|
||||
c_flush_timer = null;
|
||||
|
||||
// Configuration attributes
|
||||
Util.conf_defaults(conf, that, defaults, [
|
||||
|
@ -66,15 +66,6 @@ that.get_width = function() { return fb_width; };
|
|||
that.set_height = function (val) { that.resize(fb_width, val); };
|
||||
that.get_height = function() { return fb_height; };
|
||||
|
||||
that.set_prefer_js = function(val) {
|
||||
if (val && c_forceCanvas) {
|
||||
Util.Warn("Preferring Javascript to Canvas ops is not supported");
|
||||
return false;
|
||||
}
|
||||
conf.prefer_js = val;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -85,7 +76,7 @@ that.set_prefer_js = function(val) {
|
|||
function constructor() {
|
||||
Util.Debug(">> Display.constructor");
|
||||
|
||||
var c, func, imgTest, tval, i, curDat, curSave,
|
||||
var c, func, i, curDat, curSave,
|
||||
has_imageData = false, UE = Util.Engine;
|
||||
|
||||
if (! conf.target) { throw("target must be set"); }
|
||||
|
@ -108,70 +99,19 @@ function constructor() {
|
|||
|
||||
that.clear();
|
||||
|
||||
/*
|
||||
* Determine browser Canvas feature support
|
||||
* and select fastest rendering methods
|
||||
*/
|
||||
tval = 0;
|
||||
try {
|
||||
imgTest = c_ctx.getImageData(0, 0, 1,1);
|
||||
imgTest.data[0] = 123;
|
||||
imgTest.data[3] = 255;
|
||||
c_ctx.putImageData(imgTest, 0, 0);
|
||||
tval = c_ctx.getImageData(0, 0, 1, 1).data[0];
|
||||
if (tval === 123) {
|
||||
has_imageData = true;
|
||||
}
|
||||
} catch (exc1) {}
|
||||
|
||||
if (has_imageData) {
|
||||
Util.Info("Canvas supports imageData");
|
||||
c_forceCanvas = false;
|
||||
if (c_ctx.createImageData) {
|
||||
// If it's there, it's faster
|
||||
Util.Info("Using Canvas createImageData");
|
||||
conf.render_mode = "createImageData rendering";
|
||||
c_imageData = imageDataCreate;
|
||||
} else if (c_ctx.getImageData) {
|
||||
// I think this is mostly just Opera
|
||||
Util.Info("Using Canvas getImageData");
|
||||
conf.render_mode = "getImageData rendering";
|
||||
c_imageData = imageDataGet;
|
||||
}
|
||||
Util.Info("Prefering javascript operations");
|
||||
if (conf.prefer_js === null) {
|
||||
conf.prefer_js = true;
|
||||
}
|
||||
c_rgbxImage = rgbxImageData;
|
||||
c_cmapImage = cmapImageData;
|
||||
// Check canvas features
|
||||
if ('createImageData' in c_ctx) {
|
||||
conf.render_mode = "canvas rendering";
|
||||
} else {
|
||||
Util.Warn("Canvas lacks imageData, using fillRect (slow)");
|
||||
conf.render_mode = "fillRect rendering (slow)";
|
||||
c_forceCanvas = true;
|
||||
conf.prefer_js = false;
|
||||
c_rgbxImage = rgbxImageFill;
|
||||
c_cmapImage = cmapImageFill;
|
||||
throw("Canvas does not support createImageData");
|
||||
}
|
||||
if (conf.prefer_js === null) {
|
||||
Util.Info("Prefering javascript operations");
|
||||
conf.prefer_js = true;
|
||||
}
|
||||
|
||||
if (UE.webkit && UE.webkit >= 534.7 && UE.webkit <= 534.9) {
|
||||
// Workaround WebKit canvas rendering bug #46319
|
||||
conf.render_mode += ", webkit bug workaround";
|
||||
Util.Debug("Working around WebKit bug #46319");
|
||||
c_webkit_bug = true;
|
||||
for (func in {"fillRect":1, "copyImage":1, "rgbxImage":1,
|
||||
"cmapImage":1, "blitStringImage":1}) {
|
||||
that[func] = (function() {
|
||||
var myfunc = that[func]; // Save original function
|
||||
//Util.Debug("Wrapping " + func);
|
||||
return function() {
|
||||
myfunc.apply(this, arguments);
|
||||
if (!c_flush_timer) {
|
||||
c_flush_timer = setTimeout(flush, 100);
|
||||
}
|
||||
};
|
||||
}());
|
||||
}
|
||||
}
|
||||
// Initialize cached tile imageData
|
||||
tile16x16 = c_ctx.createImageData(16, 16);
|
||||
|
||||
/*
|
||||
* Determine browser support for setting the cursor via data URI
|
||||
|
@ -425,18 +365,6 @@ that.absY = function(y) {
|
|||
}
|
||||
|
||||
|
||||
// Force canvas redraw (for webkit bug #46319 workaround)
|
||||
flush = function() {
|
||||
var old_val;
|
||||
//Util.Debug(">> flush");
|
||||
old_val = conf.target.style.marginRight;
|
||||
conf.target.style.marginRight = "1px";
|
||||
c_flush_timer = null;
|
||||
setTimeout(function () {
|
||||
conf.target.style.marginRight = old_val;
|
||||
}, 1);
|
||||
};
|
||||
|
||||
setFillColor = function(color) {
|
||||
var rgb, newStyle;
|
||||
if (conf.true_color) {
|
||||
|
@ -498,10 +426,16 @@ that.copyImage = function(old_x, old_y, new_x, new_y, w, h) {
|
|||
* faster than direct Canvas fillStyle, fillRect rendering. In
|
||||
* gecko, Javascript array handling is much slower.
|
||||
*/
|
||||
that.getTile = function(x, y, width, height, color) {
|
||||
var img, data = [], rgb, red, green, blue, i;
|
||||
img = {'x': x, 'y': y, 'width': width, 'height': height,
|
||||
'data': data};
|
||||
that.startTile = function(x, y, width, height, color) {
|
||||
var data, rgb, red, green, blue, i;
|
||||
tile_x = x;
|
||||
tile_y = y;
|
||||
if ((width === 16) && (height === 16)) {
|
||||
tile = tile16x16;
|
||||
} else {
|
||||
tile = c_ctx.createImageData(width, height);
|
||||
}
|
||||
data = tile.data;
|
||||
if (conf.prefer_js) {
|
||||
if (conf.true_color) {
|
||||
rgb = color;
|
||||
|
@ -515,18 +449,18 @@ that.getTile = function(x, y, width, height, color) {
|
|||
data[i ] = red;
|
||||
data[i + 1] = green;
|
||||
data[i + 2] = blue;
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
} else {
|
||||
that.fillRect(x, y, width, height, color);
|
||||
}
|
||||
return img;
|
||||
};
|
||||
|
||||
that.setSubTile = function(img, x, y, w, h, color) {
|
||||
that.subTile = function(x, y, w, h, color) {
|
||||
var data, p, rgb, red, green, blue, width, j, i, xend, yend;
|
||||
if (conf.prefer_js) {
|
||||
data = img.data;
|
||||
width = img.width;
|
||||
data = tile.data;
|
||||
width = tile.width;
|
||||
if (conf.true_color) {
|
||||
rgb = color;
|
||||
} else {
|
||||
|
@ -543,25 +477,19 @@ that.setSubTile = function(img, x, y, w, h, color) {
|
|||
data[p ] = red;
|
||||
data[p + 1] = green;
|
||||
data[p + 2] = blue;
|
||||
data[p + 3] = 255;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
that.fillRect(img.x + x, img.y + y, w, h, color);
|
||||
that.fillRect(tile_x + x, tile_y + y, w, h, color);
|
||||
}
|
||||
};
|
||||
|
||||
that.putTile = function(img) {
|
||||
that.finishTile = function() {
|
||||
if (conf.prefer_js) {
|
||||
c_rgbxImage(img.x, img.y, img.width, img.height, img.data, 0);
|
||||
c_ctx.putImageData(tile, tile_x - viewport.x, tile_y - viewport.y)
|
||||
}
|
||||
// else: No-op, under gecko already done by setSubTile
|
||||
};
|
||||
|
||||
imageDataGet = function(width, height) {
|
||||
return c_ctx.getImageData(0, 0, width, height);
|
||||
};
|
||||
imageDataCreate = function(width, height) {
|
||||
return c_ctx.createImageData(width, height);
|
||||
// else: No-op, if not prefer_js then already done by setSubTile
|
||||
};
|
||||
|
||||
rgbxImageData = function(x, y, width, height, arr, offset) {
|
||||
|
@ -569,12 +497,11 @@ rgbxImageData = function(x, y, width, height, arr, offset) {
|
|||
/*
|
||||
if ((x - v.x >= v.w) || (y - v.y >= v.h) ||
|
||||
(x - v.x + width < 0) || (y - v.y + height < 0)) {
|
||||
//console.log("skipping, out of bounds: ", x, y);
|
||||
// Skipping because outside of viewport
|
||||
return;
|
||||
}
|
||||
*/
|
||||
img = c_imageData(width, height);
|
||||
img = c_ctx.createImageData(width, height);
|
||||
data = img.data;
|
||||
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
|
||||
data[i ] = arr[j ];
|
||||
|
@ -585,22 +512,9 @@ rgbxImageData = function(x, y, width, height, arr, offset) {
|
|||
c_ctx.putImageData(img, x - v.x, y - v.y);
|
||||
};
|
||||
|
||||
// really slow fallback if we don't have imageData
|
||||
rgbxImageFill = function(x, y, width, height, arr, offset) {
|
||||
var i, j, sx = 0, sy = 0;
|
||||
for (i=0, j=offset; i < (width * height); i+=1, j+=4) {
|
||||
that.fillRect(x+sx, y+sy, 1, 1, [arr[j], arr[j+1], arr[j+2]]);
|
||||
sx += 1;
|
||||
if ((sx % width) === 0) {
|
||||
sx = 0;
|
||||
sy += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cmapImageData = function(x, y, width, height, arr, offset) {
|
||||
var img, i, j, data, rgb, cmap;
|
||||
img = c_imageData(width, height);
|
||||
img = c_ctx.createImageData(width, height);
|
||||
data = img.data;
|
||||
cmap = conf.colourMap;
|
||||
for (i=0, j=offset; i < (width * height * 4); i+=4, j+=1) {
|
||||
|
@ -613,25 +527,11 @@ cmapImageData = function(x, y, width, height, arr, offset) {
|
|||
c_ctx.putImageData(img, x - viewport.x, y - viewport.y);
|
||||
};
|
||||
|
||||
cmapImageFill = function(x, y, width, height, arr, offset) {
|
||||
var i, j, sx = 0, sy = 0, cmap;
|
||||
cmap = conf.colourMap;
|
||||
for (i=0, j=offset; i < (width * height); i+=1, j+=1) {
|
||||
that.fillRect(x+sx, y+sy, 1, 1, [arr[j]]);
|
||||
sx += 1;
|
||||
if ((sx % width) === 0) {
|
||||
sx = 0;
|
||||
sy += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
that.blitImage = function(x, y, width, height, arr, offset) {
|
||||
if (conf.true_color) {
|
||||
c_rgbxImage(x, y, width, height, arr, offset);
|
||||
rgbxImageData(x, y, width, height, arr, offset);
|
||||
} else {
|
||||
c_cmapImage(x, y, width, height, arr, offset);
|
||||
cmapImageData(x, y, width, height, arr, offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1096,7 +1096,7 @@ encHandlers.RRE = function display_rre() {
|
|||
|
||||
encHandlers.HEXTILE = function display_hextile() {
|
||||
//Util.Debug(">> display_hextile");
|
||||
var subencoding, subrects, tile, color, cur_tile,
|
||||
var subencoding, subrects, color, cur_tile,
|
||||
tile_x, x, w, tile_y, y, h, xy, s, sx, sy, wh, sw, sh,
|
||||
rQ = ws.get_rQ(), rQi = ws.get_rQi();
|
||||
|
||||
|
@ -1185,7 +1185,7 @@ encHandlers.HEXTILE = function display_hextile() {
|
|||
rQi += fb_Bpp;
|
||||
}
|
||||
|
||||
tile = display.getTile(x, y, w, h, FBU.background);
|
||||
display.startTile(x, y, w, h, FBU.background);
|
||||
if (FBU.subencoding & 0x08) { // AnySubrects
|
||||
subrects = rQ[rQi];
|
||||
rQi += 1;
|
||||
|
@ -1206,10 +1206,10 @@ encHandlers.HEXTILE = function display_hextile() {
|
|||
sw = (wh >> 4) + 1;
|
||||
sh = (wh & 0x0f) + 1;
|
||||
|
||||
display.setSubTile(tile, sx, sy, sw, sh, color);
|
||||
display.subTile(sx, sy, sw, sh, color);
|
||||
}
|
||||
}
|
||||
display.putTile(tile);
|
||||
display.finishTile();
|
||||
}
|
||||
ws.set_rQi(rQi);
|
||||
FBU.lastsubencoding = FBU.subencoding;
|
||||
|
|
Loading…
Reference in New Issue