Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dlist.h

Go to the documentation of this file.
00001 /*        Copyright (C) 2000,2001,2002  Sony Computer Entertainment America
00002           
00003           This file is subject to the terms and conditions of the GNU Lesser
00004           General Public License Version 2.1. See the file "COPYING" in the
00005           main directory of this archive for more details.                             */
00006 
00007 #ifndef ps2gl_dlist_h
00008 #define ps2gl_dlist_h
00009 
00010 #include <string.h>
00011 
00012 #include "GL/gl.h"
00013 #include "ps2s/packet.h"
00014 #include "ps2gl/debug.h"
00015 
00016 /********************************************
00017  * display list commands
00018  */
00019 
00020 class CDListCmd {
00021    public:
00022       CDListCmd() {}
00023       virtual CDListCmd* Play() = 0;
00024 
00025       template <class CmdType>
00026       static inline int SizeOf() {
00027          // SEE FUNCTION below if you change anything here..
00028          int size = sizeof(CmdType);
00029          // round up to nearest quad.. this is temporary so that I
00030          // can use the vector classes for a while
00031          if ( size & 0xf )
00032             size = (size & ~0xf) + 16;
00033          return size;
00034       }
00035 
00036       template <class CmdType>
00037       static CDListCmd* GetNextCmd( CmdType *cmd ) {
00038          // for some reason gcc doesn't find the above method when called
00039          // from here... go figure.
00040          int size = sizeof(CmdType);
00041          // round up to nearest quad.. this is temporary so that I
00042          // can use the vector classes for a while
00043          if ( size & 0xf )
00044             size = (size & ~0xf) + 16;
00045 
00046          return reinterpret_cast<CDListCmd*>((unsigned int)cmd + size);
00047       }
00048 };
00049 
00050 class CEmptyListCmd : public CDListCmd {
00051    public:
00052       CDListCmd* Play() { mError("Trying to play an empty list!"); return NULL; }
00053 };
00054 
00055 class CEndListCmd : public CDListCmd {
00056    public:
00057       CDListCmd* Play() { return NULL; }
00058 };
00059 
00060 class CDListCmdBlock;
00061 class CNextBlockCmd : public CDListCmd {
00062       CDListCmdBlock    *NextBlock;
00063    public:
00064       CNextBlockCmd( CDListCmdBlock* nextBlock ) : NextBlock(nextBlock) {}
00065       CDListCmd* Play(); // defined after CDListCmdBlock
00066 };
00067 
00068 class CEnableCmd : public CDListCmd {
00069       GLenum            Property;
00070    public:
00071       CEnableCmd( GLenum prop ) : Property(prop) {}
00072       CDListCmd* Play() { glEnable( Property ); return CDListCmd::GetNextCmd(this); }
00073 };
00074 
00075 /********************************************
00076  * CDListCmdBlock
00077  */
00078 
00079 class CDListCmdBlock {
00080       static const int  ByteSize = 2048;
00081       char              Memory[ByteSize];
00082       char              *MemCursor;
00083       int               BytesLeft;
00084       CDListCmdBlock    *NextBlock;
00085 
00086    public:
00087       CDListCmdBlock()
00088          : MemCursor(Memory), BytesLeft(ByteSize), NextBlock(NULL) {
00089          CEmptyListCmd empty;
00090          memcpy( MemCursor, &empty, CDListCmd::SizeOf<CEmptyListCmd>() );
00091       }
00092       ~CDListCmdBlock() { if (NextBlock) delete NextBlock; }
00093 
00094       template <class CmdType>
00095       bool CanFit( CmdType cmd ) {
00096          return ( CDListCmd::SizeOf<CmdType>()
00097                   <= BytesLeft - CDListCmd::SizeOf<CNextBlockCmd>() );
00098       }
00099 
00100       template <class CmdType>
00101       void operator += ( CmdType cmd ) {
00102          memcpy( MemCursor, &cmd, sizeof(CmdType) ); // this should be the usual sizeof()
00103          MemCursor += CDListCmd::SizeOf<CmdType>();
00104          BytesLeft -= CDListCmd::SizeOf<CmdType>();
00105       }
00106 
00107       CDListCmd* GetFirstCmd() { return reinterpret_cast<CDListCmd*>(&Memory[0]); }
00108 
00109       void SetNextBlock( CDListCmdBlock *next ) { NextBlock = next; }
00110       CDListCmdBlock* GetNextBlock() const { return NextBlock; }
00111 };
00112 
00113 inline CDListCmd*
00114 CNextBlockCmd::Play() {
00115    return NextBlock->GetFirstCmd();
00116 }
00117 
00118 /********************************************
00119  * CDList
00120  */
00121 
00122 class CDList {
00123       static const int  kBufferMaxQwordLength = 16*1024; // 256kb
00124       CDmaPacket        *VertexBuf, *NormalBuf, *TexCoordBuf, *ColorBuf;
00125       CDListCmdBlock    *FirstCmdBlock, *CurCmdBlock;
00126       static const int  kMaxNumRenderPackets = 512;
00127       int               NumRenderPackets;
00128       CVifSCDmaPacket   *RenderPackets[kMaxNumRenderPackets];
00129 
00130    public:
00131       CDList();
00132       ~CDList();
00133 
00134       // utility
00135       template <class CmdType>
00136       CDListCmd* GetNext( CmdType* cmd ) {
00137          return 0;
00138       }
00139 
00140       template <class CmdType>
00141       void operator += ( CmdType cmd ) {
00142          if ( ! CurCmdBlock->CanFit(cmd) ) {
00143             // not enough space left in current cmd block, so terminate it
00144             // and start a new one..
00145             CDListCmdBlock *newBlock = new CDListCmdBlock;
00146             CurCmdBlock->SetNextBlock( newBlock );
00147             *CurCmdBlock += CNextBlockCmd(newBlock);
00148             CurCmdBlock = newBlock;
00149          }
00150          *CurCmdBlock += cmd;
00151       }
00152 
00153       void Play() {
00154          CDListCmd* nextCmd = FirstCmdBlock->GetFirstCmd();
00155          while ( nextCmd ) nextCmd = nextCmd->Play();
00156       }
00157 
00158       void Begin();
00159       void End() { CEndListCmd endList; *this += endList; }
00160 
00161       CDmaPacket& GetVertexBuf();
00162       CDmaPacket& GetNormalBuf();
00163       CDmaPacket& GetTexCoordBuf();
00164       CDmaPacket& GetColorBuf();
00165 
00166       void RegisterNewPacket( CVifSCDmaPacket *packet ) {
00167          RenderPackets[NumRenderPackets++] = packet;
00168       }
00169 };
00170 
00171 /********************************************
00172  * CDListManager
00173  */
00174 
00175 class CDListManager {
00176       static const int  kMaxListID = 4096;
00177       int               NextFreeListID;
00178       CDList            *Lists[kMaxListID];
00179       unsigned int      OpenListID;
00180       CDList            *OpenList;
00181 
00182       bool ListsAreFree( int firstListID, int numLists );
00183 
00184       static const int  kMaxBuffersToBeFreed = 1024;
00185       CDList*           ListsToBeFreed[2][kMaxBuffersToBeFreed];
00186       int               NumListsToBeFreed[2];
00187       int               CurBuffer;
00188 
00189       inline void AddListToBeFreed( CDList *dlist ) {
00190          mAssert( NumListsToBeFreed[CurBuffer] < kMaxBuffersToBeFreed );
00191          ListsToBeFreed[CurBuffer][NumListsToBeFreed[CurBuffer]++] = dlist;
00192       }
00193 
00194    public:
00195       CDListManager()
00196          : NextFreeListID(1), OpenListID(0), OpenList(NULL), CurBuffer(0)
00197       {
00198          for ( int i = 0; i < kMaxListID; i++ )
00199             Lists[i] = NULL;
00200          NumListsToBeFreed[0] = NumListsToBeFreed[1] = 0;
00201       }
00202       ~CDListManager() {
00203          for ( int i = 0; i < 10; i++ )
00204             if ( Lists[i] ) delete Lists[i];
00205       }
00206 
00207       void SwapBuffers();
00208 
00209       unsigned int GenLists( int numLists );
00210       void DeleteLists( unsigned int firstListID, int numLists );
00211       void NewList( unsigned int listID, GLenum mode );
00212       void EndList();
00213       void CallList( unsigned int listID );
00214 
00215       CDList& GetOpenDList() const { return *OpenList; }
00216 };
00217 
00218 #endif // ps2gl_dlist_h

ps2gl version cvs