summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2018-10-12 17:07:16 +0200
committerPierre Ossman <ossman@cendio.se>2020-06-06 13:23:05 +0200
commit224f95f9974940c4a09f294a989c3d2f32182ebe (patch)
treebe993fca52ef6f3a7d18398e01368944f055da32
parentf694c32fd5d5c53902a8c2bb4b81a7378276afef (diff)
downloadnovnc-224f95f9974940c4a09f294a989c3d2f32182ebe.tar.gz
Move tile handling to Hextile decoder
It is only used there so no need for it to be in the general Display class.
-rw-r--r--core/decoders/hextile.js55
-rw-r--r--core/display.js56
-rw-r--r--docs/API-internal.md3
-rw-r--r--tests/test.display.js35
4 files changed, 52 insertions, 97 deletions
diff --git a/core/decoders/hextile.js b/core/decoders/hextile.js
index 8dbe809..f12e7f6 100644
--- a/core/decoders/hextile.js
+++ b/core/decoders/hextile.js
@@ -13,6 +13,7 @@ export default class HextileDecoder {
constructor() {
this._tiles = 0;
this._lastsubencoding = 0;
+ this._tileBuffer = new Uint8Array(16 * 16 * 4);
}
decodeRect(x, y, width, height, sock, display, depth) {
@@ -99,7 +100,7 @@ export default class HextileDecoder {
rQi += 4;
}
- display.startTile(tx, ty, tw, th, this._background);
+ this._startTile(tx, ty, tw, th, this._background);
if (subencoding & 0x08) { // AnySubrects
let subrects = rQ[rQi];
rQi++;
@@ -122,10 +123,10 @@ export default class HextileDecoder {
const sw = (wh >> 4) + 1;
const sh = (wh & 0x0f) + 1;
- display.subTile(sx, sy, sw, sh, color);
+ this._subTile(sx, sy, sw, sh, color);
}
}
- display.finishTile();
+ this._finishTile(display);
}
sock.rQi = rQi;
this._lastsubencoding = subencoding;
@@ -134,4 +135,52 @@ export default class HextileDecoder {
return true;
}
+
+ // start updating a tile
+ _startTile(x, y, width, height, color) {
+ this._tileX = x;
+ this._tileY = y;
+ this._tileW = width;
+ this._tileH = height;
+
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+
+ const data = this._tileBuffer;
+ for (let i = 0; i < width * height * 4; i += 4) {
+ data[i] = blue;
+ data[i + 1] = green;
+ data[i + 2] = red;
+ data[i + 3] = 255;
+ }
+ }
+
+ // update sub-rectangle of the current tile
+ _subTile(x, y, w, h, color) {
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+ const xend = x + w;
+ const yend = y + h;
+
+ const data = this._tileBuffer;
+ const width = this._tileW;
+ for (let j = y; j < yend; j++) {
+ for (let i = x; i < xend; i++) {
+ const p = (i + (j * width)) * 4;
+ data[p] = blue;
+ data[p + 1] = green;
+ data[p + 2] = red;
+ data[p + 3] = 255;
+ }
+ }
+ }
+
+ // draw the current tile to the screen
+ _finishTile(display) {
+ display.blitImage(this._tileX, this._tileY,
+ this._tileW, this._tileH,
+ this._tileBuffer, 0);
+ }
}
diff --git a/core/display.js b/core/display.js
index 7b7f536..378c6f1 100644
--- a/core/display.js
+++ b/core/display.js
@@ -22,10 +22,6 @@ export default class Display {
this._fbHeight = 0;
this._prevDrawStyle = "";
- this._tile = null;
- this._tile16x16 = null;
- this._tileX = 0;
- this._tileY = 0;
Log.Debug(">> Display.constructor");
@@ -64,7 +60,6 @@ export default class Display {
throw new Error("Canvas does not support createImageData");
}
- this._tile16x16 = this._drawCtx.createImageData(16, 16);
Log.Debug("<< Display.constructor");
// ===== PROPERTIES =====
@@ -377,57 +372,6 @@ export default class Display {
});
}
- // start updating a tile
- startTile(x, y, width, height, color) {
- this._tileX = x;
- this._tileY = y;
- if (width === 16 && height === 16) {
- this._tile = this._tile16x16;
- } else {
- this._tile = this._drawCtx.createImageData(width, height);
- }
-
- const red = color[2];
- const green = color[1];
- const blue = color[0];
-
- const data = this._tile.data;
- for (let i = 0; i < width * height * 4; i += 4) {
- data[i] = red;
- data[i + 1] = green;
- data[i + 2] = blue;
- data[i + 3] = 255;
- }
- }
-
- // update sub-rectangle of the current tile
- subTile(x, y, w, h, color) {
- const red = color[2];
- const green = color[1];
- const blue = color[0];
- const xend = x + w;
- const yend = y + h;
-
- const data = this._tile.data;
- const width = this._tile.width;
- for (let j = y; j < yend; j++) {
- for (let i = x; i < xend; i++) {
- const p = (i + (j * width)) * 4;
- data[p] = red;
- data[p + 1] = green;
- data[p + 2] = blue;
- data[p + 3] = 255;
- }
- }
- }
-
- // draw the current tile to the screen
- finishTile() {
- this._drawCtx.putImageData(this._tile, this._tileX, this._tileY);
- this._damage(this._tileX, this._tileY,
- this._tile.width, this._tile.height);
- }
-
blitImage(x, y, width, height, arr, offset, fromQueue) {
if (this._renderQ.length !== 0 && !fromQueue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
diff --git a/docs/API-internal.md b/docs/API-internal.md
index f151942..1b5dfa9 100644
--- a/docs/API-internal.md
+++ b/docs/API-internal.md
@@ -104,9 +104,6 @@ None
| fillRect | (x, y, width, height, color, from_queue) | Draw a filled in rectangle
| copyImage | (old_x, old_y, new_x, new_y, width, height, from_queue) | Copy a rectangular area
| imageRect | (x, y, width, height, mime, arr) | Draw a rectangle with an image
-| startTile | (x, y, width, height, color) | Begin updating a tile
-| subTile | (tile, x, y, w, h, color) | Update a sub-rectangle within the given tile
-| finishTile | () | Draw the current tile to the display
| blitImage | (x, y, width, height, arr, offset, from_queue) | Blit pixels (of R,G,B,A) to the display
| blitRgbImage | (x, y, width, height, arr, offset, from_queue) | Blit RGB encoded image to display
| blitRgbxImage | (x, y, width, height, arr, offset, from_queue) | Blit RGBX encoded image to display
diff --git a/tests/test.display.js b/tests/test.display.js
index a853778..3492f1e 100644
--- a/tests/test.display.js
+++ b/tests/test.display.js
@@ -309,41 +309,6 @@ describe('Display/Canvas Helper', function () {
display.flush();
});
- it('should support drawing tile data with a background color and sub tiles', function () {
- display.startTile(0, 0, 4, 4, [0, 0xff, 0]);
- display.subTile(0, 0, 2, 2, [0xff, 0, 0]);
- display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
- display.finishTile();
- display.flip();
- expect(display).to.have.displayed(checkedData);
- });
-
- // We have a special cache for 16x16 tiles that we need to test
- it('should support drawing a 16x16 tile', function () {
- const largeCheckedData = new Uint8Array(16*16*4);
- display.resize(16, 16);
-
- for (let y = 0;y < 16;y++) {
- for (let x = 0;x < 16;x++) {
- let pixel;
- if ((x < 4) && (y < 4)) {
- // NB: of course IE11 doesn't support #slice on ArrayBufferViews...
- pixel = Array.prototype.slice.call(checkedData, (y*4+x)*4, (y*4+x+1)*4);
- } else {
- pixel = [0, 0xff, 0, 255];
- }
- largeCheckedData.set(pixel, (y*16+x)*4);
- }
- }
-
- display.startTile(0, 0, 16, 16, [0, 0xff, 0]);
- display.subTile(0, 0, 2, 2, [0xff, 0, 0]);
- display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
- display.finishTile();
- display.flip();
- expect(display).to.have.displayed(largeCheckedData);
- });
-
it('should support drawing BGRX blit images with true color via #blitImage', function () {
const data = [];
for (let i = 0; i < 16; i++) {