[go: nahoru, domu]

Skip to content

Commit

Permalink
Move render queue processing to Display and use requestAnimationFrame
Browse files Browse the repository at this point in the history
The imgQ code in RFB should be a generic rendering queue system in
Display.

The reason for the render queue in the first place is that images
loaded from raw data URI strings aren't immediately ready to display
so we have to wait for them to complete 'loading'. However, when data
URI images are mixed with other types of rendering actions then things
can get out of order. This is the reason for the rendering queue.

Currently this only keeps display actions for tight and tightPNG
related actions in order (because they use a mix of fills, raw pixel
data and data URI images).
  • Loading branch information
kanaka committed May 17, 2012
1 parent a0726a4 commit 34d8b84
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 37 deletions.
51 changes: 50 additions & 1 deletion include/display.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ var that = {}, // Public API methods
c_ctx = null,
c_forceCanvas = false,

// Queued drawing actions for in-order rendering
renderQ = [],

// Predefine function variables (jslint)
imageDataGet, rgbImageData, bgrxImageData, cmapImageData,
setFillColor, rescale,
setFillColor, rescale, scan_renderQ,

// The full frame buffer (logical canvas) size
fb_width = 0,
Expand Down Expand Up @@ -412,6 +415,8 @@ that.clear = function() {
c_ctx.clearRect(0, 0, viewport.w, viewport.h);
}

renderQ = [];

// No benefit over default ("source-over") in Chrome and firefox
//c_ctx.globalCompositeOperation = "copy";
};
Expand Down Expand Up @@ -582,6 +587,50 @@ that.drawImage = function(img, x, y) {
c_ctx.drawImage(img, x - viewport.x, y - viewport.y);
};

that.renderQ_push = function(action) {
renderQ.push(action);
if (renderQ.length === 1) {
// Check if it can be rendered immediately
scan_renderQ();
}
};

scan_renderQ = function() {
var a, ready = true;
while (ready && renderQ.length > 0) {
a = renderQ[0];
switch (a.type) {
case 'copy':
that.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height);
break;
case 'fill':
that.fillRect(a.x, a.y, a.width, a.height, a.color);
break;
case 'blit':
that.blitImage(a.x, a.y, a.width, a.height, a.data, 0);
break;
case 'blitRgb':
that.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0);
break;
case 'img':
if (a.img.complete) {
that.drawImage(a.img, a.x, a.y);
} else {
// We need to wait for this image to 'load'
// to keep things in-order
ready = false;
}
break;
}
if (ready) {
a = renderQ.shift();
}
}
if (renderQ.length > 0) {
requestAnimFrame(scan_renderQ);
}
};


that.changeCursor = function(pixels, mask, hotx, hoty, w, h) {
if (conf.cursor_uri === false) {
Expand Down
47 changes: 11 additions & 36 deletions include/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var that = {}, // Public API methods
pixelFormat, clientEncodings, fbUpdateRequest, fbUpdateRequests,
keyEvent, pointerEvent, clientCutText,

getTightCLength, extract_data_uri, scan_tight_imgQ,
getTightCLength, extract_data_uri,
keyPress, mouseButton, mouseMove,

checkEvents, // Overridable for testing
Expand Down Expand Up @@ -93,7 +93,6 @@ var that = {}, // Public API methods
encoding : 0,
subencoding : -1,
background : null,
imgQ : [], // TIGHT_PNG image queue
zlibs : [] // TIGHT zlib streams
},

Expand All @@ -103,7 +102,6 @@ var that = {}, // Public API methods
fb_height = 0,
fb_name = "",

scan_imgQ_rate = 40, // 25 times per second or so
last_req_time = 0,
rre_chunk_sz = 100,

Expand Down Expand Up @@ -314,7 +312,6 @@ init_vars = function() {
FBU.subrects = 0; // RRE and HEXTILE
FBU.lines = 0; // RAW
FBU.tiles = 0; // HEXTILE
FBU.imgQ = []; // TIGHT_PNG image queue
FBU.zlibs = []; // TIGHT zlib encoders
mouse_buttonMask = 0;
mouse_arr = [];
Expand Down Expand Up @@ -888,7 +885,6 @@ init_msg = function() {

/* Start pushing/polling */
setTimeout(checkEvents, conf.check_rate);
setTimeout(scan_tight_imgQ, scan_imgQ_rate);

if (conf.encrypt) {
updateState('normal', "Connected (encrypted) to: " + fb_name);
Expand Down Expand Up @@ -1409,9 +1405,9 @@ function display_tight(isTightPNG) {
}
}

FBU.imgQ.push({
'type': 'rgb',
'img': {'complete': true, 'data': dest},
display.renderQ_push({
'type': 'blitRgb',
'data': dest,
'x': FBU.x,
'y': FBU.y,
'width': FBU.width,
Expand Down Expand Up @@ -1440,9 +1436,9 @@ function display_tight(isTightPNG) {
data = decompress(ws.rQshiftBytes(clength[1]));
}

FBU.imgQ.push({
'type': 'rgb',
'img': {'complete': true, 'data': data},
display.renderQ_push({
'type': 'blitRgb',
'data': data,
'x': FBU.x,
'y': FBU.y,
'width': FBU.width,
Expand Down Expand Up @@ -1489,9 +1485,8 @@ function display_tight(isTightPNG) {
case "fill":
ws.rQshift8(); // shift off ctl
color = ws.rQshiftBytes(fb_depth);
FBU.imgQ.push({
display.renderQ_push({
'type': 'fill',
'img': {'complete': true},
'x': FBU.x,
'y': FBU.y,
'width': FBU.width,
Expand All @@ -1509,14 +1504,13 @@ function display_tight(isTightPNG) {
// clength[0] + ", clength[1]: " + clength[1]);
ws.rQshiftBytes(1 + clength[0]); // shift off ctl + compact length
img = new Image();
//img.>
FBU.imgQ.push({
img.src = "data:image/" + cmode +
extract_data_uri(ws.rQshiftBytes(clength[1]));
display.renderQ_push({
'type': 'img',
'img': img,
'x': FBU.x,
'y': FBU.y});
img.src = "data:image/" + cmode +
extract_data_uri(ws.rQshiftBytes(clength[1]));
img = null;
break;
case "filter":
Expand Down Expand Up @@ -1550,25 +1544,6 @@ extract_data_uri = function(arr) {
return ";base64," + Base64.encode(arr);
};

scan_tight_imgQ = function() {
var data, imgQ, ctx;
ctx = display.get_context();
if (rfb_state === 'normal') {
imgQ = FBU.imgQ;
while ((imgQ.length > 0) && (imgQ[0].img.complete)) {
data = imgQ.shift();
if (data.type === 'fill') {
display.fillRect(data.x, data.y, data.width, data.height, data.color);
} else if (data.type === 'rgb') {
display.blitRgbImage(data.x, data.y, data.width, data.height, data.img.data, 0);
} else {
display.drawImage(data.img, data.x, data.y);
}
}
setTimeout(scan_tight_imgQ, scan_imgQ_rate);
}
};

encHandlers.TIGHT = function () { return display_tight(false); };
encHandlers.TIGHT_PNG = function () { return display_tight(true); };

Expand Down
15 changes: 15 additions & 0 deletions include/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ if (!Array.prototype.map)
};
}

//
// requestAnimationFrame shim with setTimeout fallback
//

window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();

/*
* ------------------------------------------------------
* Namespaced in Util
Expand Down

0 comments on commit 34d8b84

Please sign in to comment.