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

Reply via email to