BufferedRefreshDoc.tioga
Bier, February 16, 1987 12:57:15 pm PST
BufferedRefresh
CEDAR 7.0 — FOR INTERNAL XEROX USE ONLY
BufferedRefresh
Getting a 1-bit display to act like N independent layers
Eric Bier
© Copyright 1987 Xerox Corporation. All rights reserved.
Abstract: Cartoonists draw scenes where some objects never move, some objects move one way, and some objects move another way. To avoid redrawing each frame from scratch, they paint picture parts on transparent layers that can be moved independently. Interactive systems like Gargoyle also profit by redrawing only the part of the scene that is moving. BufferedRefresh provides the abstraction of a "sandwich" made up of layers, each of which has its own Imager.Context. The layers are drawn back to front. The user provides a procedure to refresh each layer, and indicates which layers should have their own backing bitmap. These "backed" layers are only redrawn when the client indicates that they are no longer OK.
Created by: Bier
Maintained by: <GargoyleImplementors^.pa>
Keywords: Bitmap, Refresh, Buffer, Animation, Cartoon
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
1. History
One of the innovations that got Gargoyle off the ground was Maureen Stone's buffered refresh algorithm for rubberbanding objects. This algorithm works as follows: store the stationary objects in a bitmap. To generate each new frame, draw the background bitmap and then redraw the stretching objects. To get rid of flicker altogether, draw into yet another bitmap, the "chunking" bitmap, and dump the chunking bitmap onto the screen when it is ready.
2. Hints for using Buffered Refresh
[Artwork node; type 'ArtworkInterpress on' to command tool]
Conceptually, BufferedRefresh adds a few extra bits directly behind your screen bits. In other words, these bits are in what Imager calls viewer coordinates. Correspondingly, it adds a set of ordered layers to the client space in which the client procedures work. You choose which layer to draw on by registering your procedure with the layer, or by asking the layer to give you its Imager.Context for a while.
BufferedRefresh works with or without BiScrollers. If BiScrollers is in use, you must ask BiScrollers for the current BiScrollers transformation and tell BufferedRefresh about it. (In fact, the first thing BufferedRefresh does when it gets the screen context is UNDO the BiScrollers transformation so the sandwich bitmaps can draw in viewer coordinates as shown). Except for passing the BiScrollers transformation to BufferedRefresh, the client can ignore BiScrollers altogether.
Clients may wish to redraw part of a layer, while leaving the rest of the layer as it is. This can be done by getting the layer context, using GetLayerContext and drawing clipped to a rectangle (or some other shape for that matter). Caution: the context that comes back will include the viewerToClient transformation that was stored during the last DrawSandwich call. In other words, BufferedRefresh assumes that DrawSandwich is called each time the BiScrollers transform changed. If this is a problem, let me know.