rndstack.cpp File Reference

(r1785/r1282)

#include "camtypes.h"

Go to the source code of this file.

Classes

class  AttributeRec
 Encapsulates an item in the RenderStack class. More...

Defines

#define ITEM_SIZE   (sizeof(AttributeRec))

Variables

const INT32 InitialStackSize = 80
const INT32 StackGranularity = 30


Define Documentation

#define ITEM_SIZE   (sizeof(AttributeRec))
 

Definition at line 213 of file rndstack.cpp.


Variable Documentation

const INT32 InitialStackSize = 80
 

Technical notes:

Important note:

This class implements a rendering attribute context stack. It is done using a simple array structure, which grows when required. The stack is implemented using two classes; RenderStack and AttributeRec. The stack array is held by the RenderStack object, and the array is an array of AttributeRec objects.

The stack is optimised to avoid saving attributes when it is unnecessary. The way this works is that a 'context level' is maintained by the RenderStack object. Whenever an attribute is changed, then the render region that owns this stack pushes the current attribute onto the stack, along with the current context level. Then when the render region wants to save the context, all the stack object does is increment the context level. Hence all future attributes pushed onto the context stack will have a different context level. When the context is to be restored, the stack pops off all the stack records whose context level fields match the current context level, and then decrements the context level.

For, example, given the following sequence of calls:

pRegion->SetLineColour(COLOUR_BLACK); pRegion->SetLineWidth(250); pRegion->SaveContext(); pRegion->SetLineColour(COLOUR_RED); pRegion->SaveContext(); pRegion->SetLineColour(COLOUR_GREEN); pRegion->SetLineWidth(0); pRegion->SetFillColour(COLOUR_CYAN);

then we would end up with a stack like this:

AttributeValue Context Level

+-------------------+---------------+ | | | <--- Next free element ('Top') +-------------------+---------------+ | FillColour: CYAN | 2 | <--- Last element +-------------------+---------------+ | LineWidth: 0 | 2 | +-------------------+---------------+ | LineColour: GREEN | 2 | +-------------------+---------------+ | LineColour: RED | 1 | +-------------------+---------------+ | LineWidth: 250 | 0 | +-------------------+---------------+ | LineColour: BLACK | 0 | <--- First element +-------------------+---------------+

and the current context level would be 2. Therefore when RestoreContext() is next called, the stack pops off all elements with the context level 2, i.e. the top three elements, and decrements the context value to 1. Obviously the next time RestoreContext() is called, then it just pops off one element (red line colour) and decrements the context level to 0. And this is basically how the stack works - this way, we don't have to save/restore every attribute whenever we save/restore the context, and so it is much more efficient.

There is one more complication, because the attribute value itself is not pushed onto the stack, but a pointer to it. The advantage of this is that less data has to be copied when setting and restoring attributes, and we can encapsulate the setting and restoring of the attribute within the attribute class itself (see kernel.{h,cpp}). When an attribute is rendered, the render region asks it to render itself via its virtual function Render() - this will save the current attribute and install itself as the new current attribute via the RenderRegion::SvaeAttribute() function. Similarly, when the attribute record is popped off the stack, the virtual function Restore() is called. This will set the current attribute to be itself, via the RenderRegion::RestoreAttribute() function. At the moment (4/2/94), all our attributes our contained within the RenderRegion, so this system is not strictly needed, but if we want tools to be able to add types of attributes, then we must have an extensible system like this. At present, the current attribute array is of a fixed size, and when we start adding attributes via modules/tools, we will need to have a system of declaring/registering attributes when the modules/tools start up. They will then be given an 'ID' for their attribute. This will in fact be an index into the CurrentAttrs array maintained by RenderRegion, which will be dynamically allocated when the render region is initialised, according to how many attributes have been declared/registered.

Definition at line 206 of file rndstack.cpp.

const INT32 StackGranularity = 30
 

Definition at line 210 of file rndstack.cpp.


Generated on Sat Nov 10 03:49:20 2007 for Camelot by  doxygen 1.4.4