Panda3D
|
00001 // Filename: geomVertexArrayData.h 00002 // Created by: drose (17Mar05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef GEOMVERTEXARRAYDATA_H 00016 #define GEOMVERTEXARRAYDATA_H 00017 00018 #include "pandabase.h" 00019 #include "copyOnWriteObject.h" 00020 #include "geomVertexArrayFormat.h" 00021 #include "geomEnums.h" 00022 #include "pta_uchar.h" 00023 #include "updateSeq.h" 00024 #include "cycleData.h" 00025 #include "cycleDataReader.h" 00026 #include "cycleDataWriter.h" 00027 #include "cycleDataStageReader.h" 00028 #include "cycleDataStageWriter.h" 00029 #include "pipelineCycler.h" 00030 #include "pmap.h" 00031 #include "reMutex.h" 00032 #include "simpleLru.h" 00033 #include "vertexDataBuffer.h" 00034 #include "config_gobj.h" 00035 #include "bamReader.h" 00036 00037 class PreparedGraphicsObjects; 00038 class VertexBufferContext; 00039 class GraphicsStateGuardianBase; 00040 class GeomVertexArrayDataHandle; 00041 class VertexDataBook; 00042 class SimpleAllocatorBlock; 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Class : GeomVertexArrayData 00046 // Description : This is the data for one array of a GeomVertexData 00047 // structure. Many GeomVertexData structures will only 00048 // define one array, with all data elements interleaved 00049 // (DirectX 8.0 and before insisted on this format); 00050 // some will define multiple arrays. 00051 // 00052 // DirectX calls this concept of one array a "stream". 00053 // It also closely correlates with the concept of a 00054 // vertex buffer. 00055 // 00056 // This object is just a block of data. In general, you 00057 // should not be directly messing with this object from 00058 // application code. See GeomVertexData for the 00059 // organizing structure, and see 00060 // GeomVertexReader/Writer/Rewriter for high-level tools 00061 // to manipulate the actual vertex data. 00062 //////////////////////////////////////////////////////////////////// 00063 class EXPCL_PANDA_GOBJ GeomVertexArrayData : public CopyOnWriteObject, public SimpleLruPage, public GeomEnums { 00064 private: 00065 GeomVertexArrayData(); 00066 00067 protected: 00068 virtual PT(CopyOnWriteObject) make_cow_copy(); 00069 00070 PUBLISHED: 00071 GeomVertexArrayData(const GeomVertexArrayFormat *array_format, 00072 UsageHint usage_hint); 00073 GeomVertexArrayData(const GeomVertexArrayData ©); 00074 void operator = (const GeomVertexArrayData ©); 00075 virtual ~GeomVertexArrayData(); 00076 ALLOC_DELETED_CHAIN(GeomVertexArrayData); 00077 00078 int compare_to(const GeomVertexArrayData &other) const; 00079 00080 INLINE const GeomVertexArrayFormat *get_array_format() const; 00081 00082 INLINE UsageHint get_usage_hint() const; 00083 void set_usage_hint(UsageHint usage_hint); 00084 00085 INLINE bool has_column(const InternalName *name) const; 00086 00087 INLINE int get_num_rows() const; 00088 INLINE bool set_num_rows(int n); 00089 INLINE bool unclean_set_num_rows(int n); 00090 INLINE void clear_rows(); 00091 00092 INLINE int get_data_size_bytes() const; 00093 INLINE UpdateSeq get_modified() const; 00094 00095 void output(ostream &out) const; 00096 void write(ostream &out, int indent_level = 0) const; 00097 00098 INLINE bool request_resident() const; 00099 00100 INLINE CPT(GeomVertexArrayDataHandle) get_handle(Thread *current_thread = Thread::get_current_thread()) const; 00101 INLINE PT(GeomVertexArrayDataHandle) modify_handle(Thread *current_thread = Thread::get_current_thread()); 00102 00103 void prepare(PreparedGraphicsObjects *prepared_objects); 00104 bool is_prepared(PreparedGraphicsObjects *prepared_objects) const; 00105 00106 VertexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 00107 GraphicsStateGuardianBase *gsg); 00108 bool release(PreparedGraphicsObjects *prepared_objects); 00109 int release_all(); 00110 00111 INLINE static SimpleLru *get_independent_lru(); 00112 INLINE static SimpleLru *get_small_lru(); 00113 static void lru_epoch(); 00114 INLINE static VertexDataBook &get_book(); 00115 00116 public: 00117 virtual void evict_lru(); 00118 00119 private: 00120 INLINE void set_lru_size(size_t lru_size); 00121 00122 void clear_prepared(PreparedGraphicsObjects *prepared_objects); 00123 void reverse_data_endianness(unsigned char *dest, 00124 const unsigned char *source, size_t size); 00125 00126 00127 CPT(GeomVertexArrayFormat) _array_format; 00128 00129 // A GeomVertexArrayData keeps a list (actually, a map) of all the 00130 // PreparedGraphicsObjects tables that it has been prepared into. 00131 // Each PGO conversely keeps a list (a set) of all the Geoms that 00132 // have been prepared there. When either destructs, it removes 00133 // itself from the other's list. 00134 typedef pmap<PreparedGraphicsObjects *, VertexBufferContext *> Contexts; 00135 Contexts *_contexts; 00136 00137 // This data is only needed when reading from a bam file. 00138 class BamAuxData : public BamReader::AuxData { 00139 public: 00140 // set true to indicate the data must be endian-reversed in 00141 // finalize(). 00142 bool _endian_reversed; 00143 }; 00144 00145 // This is the data that must be cycled between pipeline stages. 00146 class EXPCL_PANDA_GOBJ CData : public CycleData { 00147 public: 00148 INLINE CData(); 00149 INLINE CData(const CData ©); 00150 INLINE void operator = (const CData ©); 00151 00152 virtual ~CData(); 00153 ALLOC_DELETED_CHAIN(CData); 00154 virtual CycleData *make_copy() const; 00155 virtual void write_datagram(BamWriter *manager, Datagram &dg, 00156 void *extra_data) const; 00157 virtual void fillin(DatagramIterator &scan, BamReader *manager, 00158 void *extra_data); 00159 virtual TypeHandle get_parent_type() const { 00160 return GeomVertexArrayData::get_class_type(); 00161 } 00162 00163 UsageHint _usage_hint; 00164 VertexDataBuffer _buffer; 00165 UpdateSeq _modified; 00166 00167 // This implements read-write locking. Anyone who gets the data for 00168 // reading or writing will hold this mutex during the lock. 00169 ReMutex _rw_lock; 00170 00171 public: 00172 static TypeHandle get_class_type() { 00173 return _type_handle; 00174 } 00175 static void init_type() { 00176 register_type(_type_handle, "GeomVertexArrayData::CData"); 00177 } 00178 00179 private: 00180 static TypeHandle _type_handle; 00181 00182 friend class GeomVertexArrayData; 00183 }; 00184 00185 PipelineCycler<CData> _cycler; 00186 typedef CycleDataReader<CData> CDReader; 00187 typedef CycleDataWriter<CData> CDWriter; 00188 typedef CycleDataStageReader<CData> CDStageReader; 00189 typedef CycleDataStageWriter<CData> CDStageWriter; 00190 00191 static SimpleLru _independent_lru; 00192 static SimpleLru _small_lru; 00193 static VertexDataBook _book; 00194 00195 public: 00196 static void register_with_read_factory(); 00197 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00198 PTA_uchar read_raw_data(BamReader *manager, DatagramIterator &source); 00199 virtual int complete_pointers(TypedWritable **plist, BamReader *manager); 00200 00201 virtual void finalize(BamReader *manager); 00202 00203 protected: 00204 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00205 void fillin(DatagramIterator &scan, BamReader *manager); 00206 00207 public: 00208 static TypeHandle get_class_type() { 00209 return _type_handle; 00210 } 00211 static void init_type() { 00212 CopyOnWriteObject::init_type(); 00213 register_type(_type_handle, "GeomVertexArrayData", 00214 CopyOnWriteObject::get_class_type()); 00215 CData::init_type(); 00216 } 00217 virtual TypeHandle get_type() const { 00218 return get_class_type(); 00219 } 00220 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00221 00222 private: 00223 static TypeHandle _type_handle; 00224 00225 friend class GeomCacheManager; 00226 friend class GeomVertexData; 00227 friend class PreparedGraphicsObjects; 00228 friend class GeomVertexArrayDataHandle; 00229 }; 00230 00231 //////////////////////////////////////////////////////////////////// 00232 // Class : GeomVertexArrayDataHandle 00233 // Description : This data object is returned by 00234 // GeomVertexArrayData::get_handle() or modify_handle(). 00235 // As long as it exists, the data is locked; when the 00236 // last of these destructs, the data is unlocked. 00237 // 00238 // Only one thread at a time may lock the data; other 00239 // threads attempting to lock the data will block. A 00240 // given thread may simultaneously lock the data 00241 // multiple times. 00242 // 00243 // This class serves in lieu of a pair of 00244 // GeomVertexArrayDataPipelineReader and 00245 // GeomVertexArrayDataPipelineWriter classes 00246 //////////////////////////////////////////////////////////////////// 00247 class EXPCL_PANDA_GOBJ GeomVertexArrayDataHandle : public ReferenceCount, public GeomEnums { 00248 private: 00249 INLINE GeomVertexArrayDataHandle(const GeomVertexArrayData *object, 00250 Thread *current_thread, 00251 const GeomVertexArrayData::CData *_cdata, 00252 bool writable); 00253 INLINE GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle &); 00254 INLINE void operator = (const GeomVertexArrayDataHandle &); 00255 00256 PUBLISHED: 00257 INLINE ~GeomVertexArrayDataHandle(); 00258 00259 public: 00260 ALLOC_DELETED_CHAIN_DECL(GeomVertexArrayDataHandle); 00261 00262 INLINE Thread *get_current_thread() const; 00263 00264 INLINE const unsigned char *get_read_pointer(bool force) const; 00265 unsigned char *get_write_pointer(); 00266 00267 PUBLISHED: 00268 INLINE const GeomVertexArrayData *get_object() const; 00269 INLINE GeomVertexArrayData *get_object(); 00270 00271 INLINE const GeomVertexArrayFormat *get_array_format() const; 00272 INLINE UsageHint get_usage_hint() const; 00273 00274 INLINE int get_num_rows() const; 00275 bool set_num_rows(int n); 00276 bool unclean_set_num_rows(int n); 00277 INLINE void clear_rows(); 00278 00279 INLINE int get_data_size_bytes() const; 00280 INLINE UpdateSeq get_modified() const; 00281 00282 INLINE bool request_resident() const; 00283 00284 void copy_data_from(const GeomVertexArrayDataHandle *other); 00285 void copy_subdata_from(size_t to_start, size_t to_size, 00286 const GeomVertexArrayDataHandle *other, 00287 size_t from_start, size_t from_size); 00288 00289 INLINE string get_data() const; 00290 void set_data(const string &data); 00291 INLINE string get_subdata(size_t start, size_t size) const; 00292 void set_subdata(size_t start, size_t size, const string &data); 00293 00294 INLINE void mark_used() const; 00295 00296 private: 00297 PT(GeomVertexArrayData) _object; 00298 Thread *_current_thread; 00299 GeomVertexArrayData::CData *_cdata; 00300 bool _writable; 00301 00302 public: 00303 static TypeHandle get_class_type() { 00304 return _type_handle; 00305 } 00306 static void init_type() { 00307 ReferenceCount::init_type(); 00308 register_type(_type_handle, "GeomVertexArrayDataHandle", 00309 ReferenceCount::get_class_type()); 00310 } 00311 00312 private: 00313 static TypeHandle _type_handle; 00314 00315 friend class GeomVertexArrayData; 00316 }; 00317 00318 INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj); 00319 00320 #include "geomVertexArrayData.I" 00321 00322 #endif