Cendio has asked me to investigate, over the coming months, the possibility of merging in some of the more advanced features from TurboVNC into TigerVNC, but some of these are potentially disruptive, and I wanted to solicit opinions from the community, in case there might be a better approach than the one I took. I'll list the features below:
(1) Lossless Refresh (LR) -- this is a non-disruptive modification to the client. It's simply a button (or a menu option) on the TigerVNC Viewer GUI that causes it to send a full framebuffer update request to the server without JPEG encoding. This is used by people who are doing image quality-sensitive work who want to ensure that they are looking at a mathematically lossless copy of the current screen image (for instance, in medical visualization, this is important.) It's also used by people who are connecting via slow networks. They can use a low quality setting for most work, then request a lossless copy whenever they are done manipulating the model and want to stare at it for a while. (2) Automatic Lossless Refresh (ALR) -- This feature is similar to LR except that, as the name implies, it's automatic. As currently implemented, it is driven by the server rather than the client. When the user starts the VNC server, they can specify -alr {t}, where {t} is the number of seconds (floating point.) The server analyzes the outgoing image stream and maintains a region consisting of all JPEG tiles sent since the last lossless refresh. If {t} seconds elapse with no updates being sent, then the server automatically sends a new update consisting of a lossless copy of the lossy region. Problems: -- This is currently implemented as a separate thread, which means introducing a dependency on libpthread in Xvnc. Not sure how people feel about that. -- It required a lot of testing to get the thread safety issues worked out in TurboVNC. However, the good news is that the issues don't come into play until the feature is activated (that is, ideally, adding the feature shouldn't destabilize the common case.) -- As implemented in TurboVNC, ALR defaults to only monitoring the regions that are drawn using X[Shm]PutImage() (but this behavior can be overridden with an environment variable.) Limiting it to PutImage requests is mainly done to avoid the "blinking cursor phenomenon"-- whereby a console window or some other 2D application uses XCopyArea() to repeatedly update a very small region of the display, and this repeated update keeps resetting the ALR timer so that the ALR is never sent. I've observed some ill-behaved window managers that will continuously update their status icons using XCopyArea(), which also causes the ALR never to be sent unless the ALR-eligible regions are limited to the regions drawn using PutImage operations. We've been discussing in the TurboVNC community the feasibility of making ALR a client-side feature. This has obvious advantages: it no longer requires a separate thread, and the feature can be turned on or off or the timeout changed on the fly. Also, it means that the feature would work with other VNC servers besides ours. However, the problem still becomes how to handle the blinking cursor phenomenon. One possibility is to assume a heuristic of not doing an ALR except for tiles of greater than a certain size. Another problem with driving ALR from the client is that a round trip is required to the server in order for the client to initiate and receive a framebuffer update. Thus, the client can't maintain a region with only the lossy tiles. It has to maintain a single "super-tile" encompassing them all, so that the ALR can be accomplished using a single FB update request. Even the single FB update request will be problematic if the latency is high enough. (3) Continuous Updates (CU) -- This feature is experimental and hasn't been released yet in TurboVNC. Basically, the problem it's designed to work around is the problem of VNC being a client-driven protocol. The client-driven nature of VNC means that it can never achieve more than 1/(ping time) updates/second on a high-latency network. People who are trying to use it on a 300 ms network are, for instance, limited to 3 updates/sec, even though they have plenty of bandwidth to push many more updates/second than this. CU takes advantage of the RFB Continuous Updates extension (this is a registered extension, not something we made up ourselves.) It is enabled via an option in the client, and when enabled on the server, PutImage (and optionally CopyArea) requests of 64k pixels are larger are sent immediately to the client without passing through the deferred update mechanism and without waiting for a framebuffer update request from the client. There are obvious problems with this whenever collaboration is enabled. CU causes all clients to be "lock-stepped" to the same frame rate (see general musings below.) There is also a lot of confusion among users as to when to use it and when not to. (4) Multi-threaded compression/decompression -- The Tight encoder in TurboVNC 1.0 and later can split the server's display evenly among the available processors and thus farm out the Tight encoding in a data parallel fashion. There are issues that had to be worked out related to thread safety, particularly as it relates to the Zlib streams (multiple threads can't share Zlib streams, so after the maximum number of Zlib streams in the Tight protocol-- 4-- is exhausted, then additional threads can't use Zlib compression.) This also introduces a dependency on pthreads in Xvnc. The biggest TurboVNC customer is using the feature with great success, and it apparently provides enough of a speedup to be worth it to them. However, to truly realize its potential, client-side multi-threading is also needed. Why this is important is that many users are starting to run TigerVNC and TurboVNC on 4+ Megapixel multi-monitor configurations. Even on modern hardware, we're limited to no more than 10 full-screen frames/second on such configurations because of the single-threaded nature of the VNC encoder and decoder. General musings on VNC architecture: Even with the above, there are still fundamental problems with the VNC architecture in high-performance implementations like TigerVNC and TurboVNC. The problem of all clients slowing down to the speed of the slowest client is a well-known phenomenon caused by a complex interaction between the speeds of the clients and the deferred update timer. In a nutshell, what happens is that if any client's frame rate drops to less than 1 / (ping time to that client), then all clients will fall into lock-step. This is worked around by ensuring that clients on slow networks use a sufficiently low JPEG quality to keep their frame rates above the required level, but it really points out how, ultimately, a lot of esoteric performance behavior could be eliminated simply by implementing a proper frame spoiling mechanism. This would eliminate the need for the CU feature as well. A proper frame spoiling mechanism would have a separate image queue and dispatch thread for each connected client, so that all of the clients could be driven at their own frame rates without requiring a client-driven protocol or a deferred update timer. This is not only disruptive but possibly even violates the fundamental nature of the RFB protocol, but we're to the point where we're going to have great difficulty making TigerVNC a viable solution for high-latency networks unless we revisit things like this. ------------------------------------------------------------------------------ AppSumo Presents a FREE Video for the SourceForge Community by Eric Ries, the creator of the Lean Startup Methodology on "Lean Startup Secrets Revealed." This video shows you how to validate your ideas, optimize your ideas and identify your business strategy. http://p.sf.net/sfu/appsumosfdev2dev _______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel