00001 /* 00002 * This file contains class that represents queue of frames that comes from 00003 * dispatcher and wait for displaying in renderer. 00004 * 00005 * Author: 00006 * Tomas Mrkvicka 00007 * xmrkvi03@stud.fit.vutbr.cz 00008 * 00009 */ 00010 #include <cassert> 00011 00012 #include "pipeline/FrameQueue.h" 00013 00014 //////////////////////////////////////////////////////////////////////////////// 00015 //////////////////////////////////////////////////////////////////////////////// 00016 //////////////////////////////////////////////////////////////////////////////// 00017 // TFrameQueue 00018 00019 /** Konstruktor. 00020 * 00021 * Vytvori frontu s vnitrnim bufferem s delkou 0. 00022 * Snimky tedy lze zobrazit okamzite pote co nemaji zadny zamek. 00023 */ 00024 TFrameQueue::TFrameQueue(void) 00025 { 00026 m_length = 0; 00027 } 00028 //OK 2007-08-25 12:07:17 B04-315B\Tom 00029 00030 /** Destruktor. 00031 * 00032 * Odstrani vsechny snimky z fronty - tj. na kazdy snimek zavola Release(). 00033 */ 00034 TFrameQueue::~TFrameQueue(void) 00035 { 00036 m_critical.Enter(); 00037 00038 while( ! m_frames.empty() ) 00039 { 00040 TFrameReal * f = m_frames.front(); 00041 if ( f ) f->Release(); 00042 m_frames.pop(); 00043 } 00044 00045 m_critical.Leave(); 00046 } 00047 //OK 2007-08-25 12:09:13 B04-315B\Tom 00048 00049 /** Prida snimek do fronty. Zvysi pocet referenci na tento snimek. 00050 * 00051 * Fronta udrzuje pouze referenci na snimek, nikdy neudrzuje zamek. 00052 * 00053 * \note Metoda by mela byt volana z dispatcheru. 00054 * 00055 * \param frame [in] pridavany snimek, fronta zvysi pocet referenci na tento snimek o 1 00056 */ 00057 void TFrameQueue::AddFrame( TFrameReal * frame ) 00058 { 00059 m_critical.Enter(); 00060 00061 //pridame snimek do vnitrniho bufferu 00062 frame->AddRefs(); 00063 m_buffer.push( frame ); 00064 00065 //pokud vstupni buffer presahl svou velikost pak presuneme snimky do 00066 //vystupni fronty 00067 while( m_buffer.size() > m_length ) 00068 { 00069 m_frames.push( m_buffer.front() ); 00070 m_buffer.pop(); 00071 } 00072 00073 m_critical.Leave(); 00074 } 00075 //OK 2007-08-25 12:09:41 B04-315B\Tom 00076 00077 /** Vrati snimek pripraveny pro zobrazeni. Tento snimek je odstranen z fronty. 00078 * 00079 * Muze vratit NULL pokud neni zadny snimek pripraven ke zobrazeni. 00080 * To se muze stat v pripade ze je fronta prazdna nebo pokud je snimek zamceny. 00081 * 00082 * \warning Volajici objekt je zodpovedny za vraceny objekt (referenci)!!! 00083 */ 00084 TFrameReal* TFrameQueue::GetRenderableFrame(void) 00085 { 00086 TFrameReal * frame = NULL; 00087 00088 m_critical.Enter(); 00089 //pokud je fronta prazdna pak se nic nedeje 00090 if( m_frames.empty() ) 00091 { 00092 frame = NULL; 00093 } 00094 else 00095 { 00096 //zjistime zda se na zacatku ve fronte nachazi renderovatelny snimek - nema zamky 00097 frame = m_frames.front(); 00098 00099 if( frame->GetLockCount() == 0 ) 00100 { 00101 //snimek nema zamky - nebudem pridavat reference, pouze odstranime z fronty a vratime 00102 m_frames.pop(); 00103 } 00104 else 00105 { 00106 //objekt ma zamky - neni mozne jej vyzvednout z fronty 00107 frame = NULL; 00108 } 00109 } 00110 m_critical.Leave(); 00111 00112 return frame; 00113 } 00114 //OK 2007-08-25 12:10:07 B04-315B\Tom 00115 00116 /** Vrati maximalni velikost vnitrniho bufferu. 00117 */ 00118 DWORD TFrameQueue::GetInputBufferLength(void) const 00119 { 00120 return m_length; 00121 } 00122 00123 /** Nastavi novou velikost pro vnitrni buffer. 00124 * 00125 * Pokud je velikost mensi nez aktualni velikost bufferu pak jsou polozky presunuty do vystupni fronty. 00126 * 00127 * \param length [in] nova velikost vnitrniho bufferu 00128 */ 00129 void TFrameQueue::SetInputBufferLength( DWORD length ) 00130 { 00131 m_critical.Enter(); 00132 00133 while ( length < m_buffer.size() ) 00134 { 00135 //buffer obsahuje vic polozek nez je jeho nova delka - presunujeme do vystupni fronty 00136 m_frames.push( m_buffer.front() ); 00137 m_buffer.pop(); 00138 } 00139 00140 //nova delka vnitrniho bufferu 00141 m_length = length; 00142 00143 m_critical.Leave(); 00144 } 00145 00146 /** Metoda odstrani z fronty vsechny snimky. 00147 * 00148 * Metoda by mela byt volana na konci aplikace pred odstranenim objektu. 00149 */ 00150 void TFrameQueue::Free(void) 00151 { 00152 m_critical.Enter(); 00153 while( ! m_frames.empty() ) 00154 { 00155 TFrameReal * f = m_frames.front(); 00156 if ( f ) f->Release(); 00157 m_frames.pop(); 00158 } 00159 00160 while ( ! m_buffer.empty() ) 00161 { 00162 TFrameReal * f = m_buffer.front(); 00163 if ( f ) f->Release(); 00164 m_buffer.pop(); 00165 } 00166 m_critical.Leave(); 00167 } 00168 //OK 2007-08-25 12:10:37 B04-315B\Tom 00169 00170 // TFrameQueue 00171 //////////////////////////////////////////////////////////////////////////////// 00172 //////////////////////////////////////////////////////////////////////////////// 00173 ////////////////////////////////////////////////////////////////////////////////