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

ps2gl version 0.2