diff options
author | Pierre Ossman <ossman@cendio.se> | 2018-10-12 17:07:16 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2020-06-06 13:23:05 +0200 |
commit | 224f95f9974940c4a09f294a989c3d2f32182ebe (patch) | |
tree | be993fca52ef6f3a7d18398e01368944f055da32 | |
parent | f694c32fd5d5c53902a8c2bb4b81a7378276afef (diff) | |
download | novnc-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.js | 55 | ||||
-rw-r--r-- | core/display.js | 56 | ||||
-rw-r--r-- | docs/API-internal.md | 3 | ||||
-rw-r--r-- | tests/test.display.js | 35 |
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++) { |