diff --git a/include/canvas.js b/include/canvas.js
index 41d9459118c0d31faaca12887df23de86ed47907..0f38e0657682ac73edfdc6dbd3a14eef022e0b34 100644
--- a/include/canvas.js
+++ b/include/canvas.js
@@ -46,6 +46,8 @@ cdef('focused',        'bool', true, 'Capture and send key strokes');
 cdef('colourMap',      'raw',  [], 'Colour map array (not true color)');
 cdef('scale',          'float', 1, 'VNC viewport scale factor');
 
+cdef('render_mode',    'str', '', 'Canvas rendering mode (read-only)');
+
 // Override some specific getters/setters
 that.set_prefer_js = function(val) {
     if (val && c_forceCanvas) {
@@ -72,6 +74,8 @@ that.set_colourMap = function(val, idx) {
     }
 };
 
+that.set_render_mode = function () { throw("render_mode is read-only"); };
+
 // Add some other getters/setters
 that.get_width = function() {
     return c_width;
@@ -135,9 +139,12 @@ function constructor() {
         if (ctx.createImageData) {
             // If it's there, it's faster
             Util.Info("Using Canvas createImageData");
+            conf.render_mode = "createImageData rendering";
             that.imageData = that.imageDataCreate;
         } else if (ctx.getImageData) {
+            // I think this is mostly just Opera
             Util.Info("Using Canvas getImageData");
+            conf.render_mode = "getImageData rendering";
             that.imageData = that.imageDataGet;
         }
         Util.Info("Prefering javascript operations");
@@ -148,6 +155,7 @@ function constructor() {
         that.cmapImage = that.cmapImageData;
     } else {
         Util.Warn("Canvas lacks imageData, using fillRect (slow)");
+        conf.render_mode = "fillRect rendering (slow)";
         c_forceCanvas = true;
         conf.prefer_js = false;
         that.rgbxImage = that.rgbxImageFill;
diff --git a/include/rfb.js b/include/rfb.js
index f904936fe11c2ccb49d95dfec981ae1ff76a8b02..38812704618772e71610cc9d35f5cd7620aba907 100644
--- a/include/rfb.js
+++ b/include/rfb.js
@@ -209,7 +209,7 @@ function rQshiftBytes(len) {
 
 // Create the public API interface and initialize
 function constructor() {
-    var i;
+    var i, rmode;
     Util.Debug(">> RFB.constructor");
 
     // Create lookup tables based encoding number
@@ -225,13 +225,14 @@ function constructor() {
         Util.Error("Canvas exception: " + exc);
         updateState('fatal', "No working Canvas");
     }
+    rmode = canvas.get_render_mode();
 
     init_vars();
 
     /* Check web-socket-js if no builtin WebSocket support */
     if (VNC_native_ws) {
         Util.Info("Using native WebSockets");
-        updateState('loaded', 'noVNC ready (using native WebSockets)');
+        updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode);
     } else {
         Util.Warn("Using web-socket-js flash bridge");
         if ((! Util.Flash) ||
@@ -241,7 +242,7 @@ function constructor() {
             updateState('fatal',
                     "'file://' URL is incompatible with Adobe Flash");
         } else {
-            updateState('loaded', 'noVNC ready (using Flash WebSockets emulation)');
+            updateState('loaded', 'noVNC ready: WebSockets emulation, ' + rmode);
         }
     }