|
|
@@ -0,0 +1,197 @@
|
|
|
+<html>
|
|
|
+ <head>
|
|
|
+ <title>VNC Performance Benchmark</title>
|
|
|
+ <link rel="stylesheet" href="include/plain.css">
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+
|
|
|
+ Passes: <input id='passes' style='width:50' value=3>
|
|
|
+
|
|
|
+ <input id='startButton' type='button' value='Start' style='width:100px'
|
|
|
+ onclick="start();" disabled>
|
|
|
+
|
|
|
+ <br><br>
|
|
|
+
|
|
|
+ Results:<br>
|
|
|
+ <textarea id="messages" style="font-size: 9;" cols=80 rows=15></textarea>
|
|
|
+
|
|
|
+ <br><br>
|
|
|
+
|
|
|
+ <div id="VNC_screen">
|
|
|
+ <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">
|
|
|
+ <table border=0 width=100%><tr>
|
|
|
+ <td><div id="VNC_status">Loading</div></td>
|
|
|
+ </tr></table>
|
|
|
+ </div>
|
|
|
+ <canvas id="VNC_canvas" width="640px" height="20px">
|
|
|
+ Canvas not supported.
|
|
|
+ </canvas>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </body>
|
|
|
+
|
|
|
+ <!--
|
|
|
+ <script type='text/javascript'
|
|
|
+ src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
|
|
+ -->
|
|
|
+
|
|
|
+ <script src="include/vnc.js"></script>
|
|
|
+ <script src="include/playback.js"></script>
|
|
|
+ <script src="data_multi.js"></script>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ var start_time, VNC_frame_data, pass, passes, encIdx,
|
|
|
+ encOrder = ['raw', 'rre', 'hextile', 'tightpng', 'copyrect'],
|
|
|
+ encTot = {}, encMin = {}, encMax = {},
|
|
|
+ passCur, passTot, passMin, passMax;
|
|
|
+
|
|
|
+ function msg(str) {
|
|
|
+ console.log(str);
|
|
|
+ var cell = $('messages');
|
|
|
+ cell.innerHTML += str + "\n";
|
|
|
+ cell.scrollTop = cell.scrollHeight;
|
|
|
+ }
|
|
|
+ function dbgmsg(str) {
|
|
|
+ if (Util.get_logging() === 'debug') {
|
|
|
+ msg(str);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ updateState = function (rfb, state, oldstate, mesg) {
|
|
|
+ switch (state) {
|
|
|
+ case 'failed':
|
|
|
+ case 'fatal':
|
|
|
+ msg("noVNC sent '" + state +
|
|
|
+ "' state during pass " + pass +
|
|
|
+ ", iteration " + iteration +
|
|
|
+ " frame " + frame_idx);
|
|
|
+ test_state = 'failed';
|
|
|
+ break;
|
|
|
+ case 'loaded':
|
|
|
+ $('startButton').disabled = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (typeof mesg !== 'undefined') {
|
|
|
+ $('VNC_status').innerHTML = mesg;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function start() {
|
|
|
+ $('startButton').value = "Running";
|
|
|
+ $('startButton').disabled = true;
|
|
|
+
|
|
|
+ mode = 'perftest'; // full-speed
|
|
|
+ passes = $('passes').value;
|
|
|
+ pass = 1;
|
|
|
+ encIdx = 0;
|
|
|
+
|
|
|
+ // Render each encoding once for each pass
|
|
|
+ iterations = 1;
|
|
|
+
|
|
|
+ // Initialize stats counters
|
|
|
+ for (i = 0; i < encOrder.length; i++) {
|
|
|
+ enc = encOrder[i];
|
|
|
+ encTot[i] = 0;
|
|
|
+ encMin[i] = 2<<23; // Something sufficiently large
|
|
|
+ encMax[i] = 0;
|
|
|
+ }
|
|
|
+ passCur = 0;
|
|
|
+ passTot = 0;
|
|
|
+ passMin = 2<<23;
|
|
|
+ passMax = 0;
|
|
|
+
|
|
|
+ // Fire away
|
|
|
+ next_encoding();
|
|
|
+ }
|
|
|
+
|
|
|
+ function next_encoding() {
|
|
|
+ var encName;
|
|
|
+
|
|
|
+ if (encIdx >= encOrder.length) {
|
|
|
+ // Accumulate pass stats
|
|
|
+ if (passCur < passMin) {
|
|
|
+ passMin = passCur;
|
|
|
+ }
|
|
|
+ if (passCur > passMax) {
|
|
|
+ passMax = passCur;
|
|
|
+ }
|
|
|
+ msg("Pass " + pass + " took " + passCur + " ms");
|
|
|
+
|
|
|
+ passCur = 0;
|
|
|
+ encIdx = 0;
|
|
|
+ pass += 1;
|
|
|
+ if (pass > passes) {
|
|
|
+ // We are finished
|
|
|
+ rfb.get_canvas().stop(); // Shut-off event interception
|
|
|
+ $('startButton').disabled = false;
|
|
|
+ $('startButton').value = "Start";
|
|
|
+ finish_passes();
|
|
|
+ return; // We are finished, terminate
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ encName = encOrder[encIdx];
|
|
|
+ dbgmsg("Rendering pass " + pass + " encoding '" + encName + "'");
|
|
|
+
|
|
|
+ VNC_frame_data = VNC_frame_data_multi[encName];
|
|
|
+ iteration = 0;
|
|
|
+ start_time = (new Date()).getTime();
|
|
|
+
|
|
|
+ next_iteration();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Finished rendering current encoding
|
|
|
+ function finish() {
|
|
|
+ var total_time, end_time = (new Date()).getTime();
|
|
|
+ total_time = end_time - start_time;
|
|
|
+
|
|
|
+ dbgmsg("Encoding " + encOrder[encIdx] + " took " + total_time + "ms");
|
|
|
+
|
|
|
+ passCur += total_time;
|
|
|
+ passTot += total_time;
|
|
|
+
|
|
|
+ // Accumulate stats
|
|
|
+ encTot[encIdx] += total_time;
|
|
|
+ if (total_time < encMin[encIdx]) {
|
|
|
+ encMin[encIdx] = total_time;
|
|
|
+ }
|
|
|
+ if (total_time > encMax[encIdx]) {
|
|
|
+ encMax[encIdx] = total_time;
|
|
|
+ }
|
|
|
+
|
|
|
+ encIdx += 1;
|
|
|
+ next_encoding();
|
|
|
+ }
|
|
|
+
|
|
|
+ function finish_passes() {
|
|
|
+ var i, enc, avg, passAvg;
|
|
|
+ msg("STATS (for " + passes + " passes)");
|
|
|
+ // Encoding stats
|
|
|
+ for (i = 0; i < encOrder.length; i++) {
|
|
|
+ enc = encOrder[i];
|
|
|
+ avg = (encTot[i] / passes).toFixed(1);
|
|
|
+ msg(" " + enc + ": " + encTot[i] + " ms, " +
|
|
|
+ encMin[i] + "/" + avg + "/" + encMax[i] +
|
|
|
+ " (min/avg/max)");
|
|
|
+
|
|
|
+ }
|
|
|
+ // Print pass stats
|
|
|
+ passAvg = (passTot / passes).toFixed(1);
|
|
|
+ msg("\n All passes: " + passTot + " ms, " +
|
|
|
+ passMin + "/" + passAvg + "/" + passMax +
|
|
|
+ " (min/avg/max)");
|
|
|
+ }
|
|
|
+
|
|
|
+ window.onload = function() {
|
|
|
+ var i, enc;
|
|
|
+ dbgmsg("Frame lengths:");
|
|
|
+ for (i = 0; i < encOrder.length; i++) {
|
|
|
+ enc = encOrder[i];
|
|
|
+ dbgmsg(" " + enc + ": " + VNC_frame_data_multi[enc].length);
|
|
|
+ }
|
|
|
+ rfb = RFB({'target': 'VNC_canvas',
|
|
|
+ 'updateState': updateState});
|
|
|
+ rfb.testMode(send_array);
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+</html>
|