home *** CD-ROM | disk | FTP | other *** search
-
- // This object tracks the dirty rectangle of the frame buffer.
- // If two rects overlap, they are coalesced. If they don't
- // overlap, they are kept separate. This way, when a redraw
- // is done, we have two flushes that are small rather than one
- // large flush. (The large flush would draw *lots* of unnecessary
- // pixels!)
-
- // Many thanks to Sam Streeper for giving me the idea to create this object.
- // It was originally based upon code snippets which he gave me, taken from
- // the game BoinkOut. Thanks, Sam!
-
- // Since Sam's suggestions, I have tried to speed up this object while
- // adding code to allow tuning of the algorithm to various situations.
- // You have two parameters: how often should rects be coalesced and
- // when to coalesce.
- // The first param works like this... the algorithm to do the
- // coalesce is O(n^3). Thus, we want to keep n as small as possible.
- // hence, how often should we do a coalesce? if often enough, we keep
- // n reasonable (hopefully) and if too often, we waste time checking
- // for possible coalescing that doesn't exist...
- // The next param is based on when to coalesce. Basically, the idea
- // of tracking dirty rects is to keep from flushing clean parts of the
- // buffer. Now, if two rects overlap by only a pixel, and then we do
- // a coalesce, then we re-draw a lot of clean area: (clean is "C")
- // +----+
- // | | C
- // +----+----+
- // C | |
- // +----+
- // In such a case, we probably shouldn't coalesce. On the other hand,
- // if the overlapping rects overlap by a lot, we want to coalesce so that
- // we don't redraw much of the dirty parts of the buffer twice. So, you
- // set the do it/don't do it threshold by setting the percent of dirty area
- // versus coalesced area. If there isn't at least that much dirty area in
- // relation to the coalesced area, then the coalesce won't happen. Note
- // that 50% and below will always coalesce!
-
- #import <appkit/appkit.h>
-
- #define MAX_RECTS 1024 // should be more than enough, and it's easier than
- // making it dynamic. (Not that I couldn't.... :-) )
-
- extern BOOL coalesce(NXRect *p1, NXRect *p2, double percent);
-
- @interface DirtPile:Object
- {
- int maxRects; // max number of rects in list
- int numRects; // number of rects in list
- NXRect rectList[MAX_RECTS]; // list of dirty rects
- BOOL allDirty; // set if you want next flush to be everything
- NXColor noBufferColor;
- double percentOverlap; // how much overlap (%) before we coalesce?
- int coalesceFrequency; // coalesce after every X rects added
- int rectsAdded;
- BOOL manyFlushes;
- }
-
- - init; // initialize the instance
- - addRegion:(float)x :(float)y :(float)w :(float)h; // add a dirty rect
- - addRegion:(const NXRect *)rect; // add a dirty rect
- - fullRedraw:sender :buffer; // assumed to be a view
- - doRedraw:buffer; // flush dirty rects from buffer to screen
- - setAllDirty; // makes next flush be whole buffer
- - sendDirtTo:aDirtPile; // add all our dirty rects to aDirtPile
- - setNoBufferColor:(NXColor)aColor; // set color to draw if no buffer
- - (double)percentDirtyForCoalesce;
- - setPercentDirtyForCoalesce:(double)val;
- - (BOOL)manyFlushes;
- - setManyFlushes:(BOOL)flag;
-
- @end
-