Fog Creek Software
Discussion Board




Remote Access and Double Buffering

Remote access (Terminal Services, VNC) seems to be a hot topic among JoS readers, so perhaps one of you might be knowledgable about the following:

I have a piece of software developed in-house that does updates the screen using an intermediate ("double") buffer - the program first creates an in memory bitmap with all the data, and then copies the bitmap whole to the screen. This avoids flicker entirely (even though parts of the picture are drawn over several times during the making of the picture), and in some setups significantly speeds up everything, probably because reading/writing main memory works better than video memory.

However, we now wish to run it remotely through dial-up. Screen copiers (VNC, DameWare, NetMeeting and if I am not mistaken PC Anywhere) don't care one bit how an image is generated, as they just copy the screen. Unfortunately, they take up too much bandwidth to make this effective. We're considering a Terminal Services / RDP solution, but it will take us some time before we can test it in a low bandwidth situation.

So ... Does anyone know how terminal services would manage with a double buffered solution? Will it have to transfer the intermediate buffer across the line every time, or will it compose the intermediate buffer locally on the RDP client?

And, while I'm at it, those of you looking for remote control apps, check DameWare [ http://dameware.com , I think, I can't check now ]. It's a complete management system with, among others, a VNC-style remoter that works extremely well. The bandwidth requirements are too much for practically using the computer through a dial-up, but if you have the bandwidth, this is a very good remote administration tool. Not affiliated with them in any way, and have not yet decided to buy it myself, but the demo is awesome.

Ori Berger
Wednesday, February 19, 2003

I guess I'm confused on what this software you've developed actually does.  Does it simply display the screen of one computer on a remote computer and the remote computer uses double buffering to display the screen?

I used double buffering techniques all the time in games.  If it's display is timed with the vertical refresh it avoids flicker.

If you could explain your software in more detail it would help. (Maybe it's just me that can't understand it though.)

Maybe you could try compressing the image then sending it?

A guy
Wednesday, February 19, 2003

Ok, a clarification:

The program is actually some kind of monitor, that collects many data items, consolidates them to a nice display, and presents that display locally. It does that frequently, often 5 times a second. It also has some user interaction, but the user interaction is less important -- it's mainly a monitoring app. It uses double buffering because data is presented graphically and updated frequently, and it looked like the best way to avoid flicker (and still does look that way). The buffer switching need not be synchronized with the vertical retrace or anything.

It was written without any regard for network transparency or remote operation -- and it looks like I will need to operate it remotely through a dial-up or slightly faster (but not much faster) connection. I would rather not rewrite it to work in a distributed manner over a network (It's not yet declared broken, and if it ain't broken ...). Screen copy remoters, such as VNC, DameWare, WebEx and NetMeeting copy the whole screen, and as a result they take too much bandwidth to update the remote display in real-time. Terminal Services / RDP passes the GDI calls to the other side instead, which potentially allows my application to run remotely through a dial-up in real time (assuming, of course, that the GDI operations are encoded with sufficient efficiency, but most anyone I've asked believes they are).

And now we come to the problem - I know if I drop the double buffering, the remote display will work ok but will flicker horribly (unless terminal services has some magic to avoid that -- I'd be surprised). But what happens to bandwidth usage if I keep using double buffering?

And to concisely rephrase the question again:

Does Terminal Services manage the off-screen bitmaps on the RDP server, or on the RDP client?

Thanks.

Ori Berger
Wednesday, February 19, 2003

With double-buffering, you're blitting pixels to the screen, so Terminal Server can't take advantage of higher-level constructs to reduce bandwidth.

Maybe you could detect that you're running on a remote session, and turn off double-buffering in that case?

See http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/win2kts/maintain/optimize/tsappdev.asp

Rob
Wednesday, February 19, 2003

Thanks, rob; That's what I thought I should do in case TS does not handle it well, but now I'm even more confused - from the link you posted:

"Similarly, if an application needs to do elaborate screen output, such as overlaying several images to arrive at a final composite screen, the application should do that work in an off-screen buffer and then send the results to the actual video buffer."

Well, that's my case - except that I need to do that several times per second. So it looks like I lose either way - either it will flicker, or it will eat up bandwidth.

Am I missing something? Does anyone has another suggestion (keeping in mind that making the program do the remoting itself is my _last_ resort?)

Ori Berger
Wednesday, February 19, 2003

Maybe you should only update it once every 1-3 seconds  when opened in a terminal server session.

GiorgioG
Wednesday, February 19, 2003

If you're only updating every five seconds, is display performance really an issue?

Superman
Wednesday, February 19, 2003

Have you looked at TightVNC (http://www.tightvnc.com/)?  It compresses the data transmitted.

-Thomas

Thomas
Wednesday, February 19, 2003

Giorgio - That's the rate I get with VNC or DameWare without changing the software; But I really do want to update it in real time or nearly realtime.

Superman - That's 5 times per second, not once per 5 seconds.

Thomas - I have checked TightVNC - and while it is better in using bandwidth than others (especially in JPEG mode), it takes a lot of CPU cycles and still doesn't give 'instant' update (I'm not sure, but I think that - like DameWare - it does a continuous scan rather than snapshots, which result in a very messy updates when the screen has high update frequency - the remote screen gets different 16x16 blocks from different frames).

And to all those who wonder - what is interesting about the data in question is its dynamics, not its state, which is why the update frequency is as high as it is. It is probably possible to find a representation that captures the same information in a less volatile way, but that would mean a major change. As it is, staring at the monitoring app screen for less than four seconds lets an experienced person see everything about the dynamic state of the system. Some graphs might match that information transfer capacity, but we haven't found them yet. (and when we do, we will use them, but I assume that would require significant work).

And,  no, I can't tell you what kind of data that is or why the real time update is so important, because if I did, I'd have to shoot you. [At least that's what the NDA I signed would require me do.....].

And now that I think of it, the mystery makes it look so much more interesting than it really is :)

Ori Berger
Wednesday, February 19, 2003


Your current double-buffering scheme is just about optimal for Terminal Services.

Terminal Services hooks into the GDI and redirects only operations that write directly to the video device.  It does not redirect operations on your in-memory buffer, as long as you used a compatible DC and not a DIB Section that might reside in video memory.

I assume that your rendering consists of bitmap manipulation anyway, and that you do all your rendering operations in your in-memory buffer before calling BitBlt() to write the whole thing to the display. The only operation sent to the client is the final BitBlt().  This will give you vastly superior performance compared to performing all of the rendering directly onto the device.

The situation is slightly different if you are doing high-level operations (like TextOut() ) only.  In that case, Terminal Services could intercept the TextOut call *before* it resolves to a bitmap operation.  Even in this situation, you will quickly reach a point where bitmap operations are faster even if you use only a few higher level operations in the same region.

The secret to performance in this environment is to draw as few times as possible and to restrict your drawing to the smallest possible update rectangle.  Double-buffering is a key technique in getting this to work.

Craig
Wednesday, February 19, 2003

*  Recent Topics

*  Fog Creek Home