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 bool reserve_num_rows(int n); 00091 INLINE void clear_rows(); 00092 00093 INLINE int get_data_size_bytes() const; 00094 INLINE UpdateSeq get_modified() const; 00095 00096 void output(ostream &out) const; 00097 void write(ostream &out, int indent_level = 0) const; 00098 00099 INLINE bool request_resident() const; 00100 00101 INLINE CPT(GeomVertexArrayDataHandle) get_handle(Thread *current_thread = Thread::get_current_thread()) const; 00102 INLINE PT(GeomVertexArrayDataHandle) modify_handle(Thread *current_thread = Thread::get_current_thread()); 00103 00104 void prepare(PreparedGraphicsObjects *prepared_objects); 00105 bool is_prepared(PreparedGraphicsObjects *prepared_objects) const; 00106 00107 VertexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 00108 GraphicsStateGuardianBase *gsg); 00109 bool release(PreparedGraphicsObjects *prepared_objects); 00110 int release_all(); 00111 00112 INLINE static SimpleLru *get_independent_lru(); 00113 INLINE static SimpleLru *get_small_lru(); 00114 static void lru_epoch(); 00115 INLINE static VertexDataBook &get_book(); 00116 00117 public: 00118 virtual void evict_lru(); 00119 00120 private: 00121 INLINE void set_lru_size(size_t lru_size); 00122 00123 void clear_prepared(PreparedGraphicsObjects *prepared_objects); 00124 void reverse_data_endianness(unsigned char *dest, 00125 const unsigned char *source, size_t size); 00126 00127 00128 CPT(GeomVertexArrayFormat) _array_format; 00129 00130 // A GeomVertexArrayData keeps a list (actually, a map) of all the 00131 // PreparedGraphicsObjects tables that it has been prepared into. 00132 // Each PGO conversely keeps a list (a set) of all the Geoms that 00133 // have been prepared there. When either destructs, it removes 00134 // itself from the other's list. 00135 typedef pmap<PreparedGraphicsObjects *, VertexBufferContext *> Contexts; 00136 Contexts *_contexts; 00137 00138 // This data is only needed when reading from a bam file. 00139 class BamAuxData : public BamReader::AuxData { 00140 public: 00141 // set true to indicate the data must be endian-reversed in 00142 // finalize(). 00143 bool _endian_reversed; 00144 }; 00145 00146 // This is the data that must be cycled between pipeline stages. 00147 class EXPCL_PANDA_GOBJ CData : public CycleData { 00148 public: 00149 INLINE CData(); 00150 INLINE CData(const CData ©); 00151 INLINE void operator = (const CData ©); 00152 00153 virtual ~CData(); 00154 ALLOC_DELETED_CHAIN(CData); 00155 virtual CycleData *make_copy() const; 00156 virtual void write_datagram(BamWriter *manager, Datagram &dg, 00157 void *extra_data) const; 00158 virtual void fillin(DatagramIterator &scan, BamReader *manager, 00159 void *extra_data); 00160 virtual TypeHandle get_parent_type() const { 00161 return GeomVertexArrayData::get_class_type(); 00162 } 00163 00164 UsageHint _usage_hint; 00165 VertexDataBuffer _buffer; 00166 UpdateSeq _modified; 00167 00168 // This implements read-write locking. Anyone who gets the data for 00169 // reading or writing will hold this mutex during the lock. 00170 ReMutex _rw_lock; 00171 00172 public: 00173 static TypeHandle get_class_type() { 00174 return _type_handle; 00175 } 00176 static void init_type() { 00177 register_type(_type_handle, "GeomVertexArrayData::CData"); 00178 } 00179 00180 private: 00181 static TypeHandle _type_handle; 00182 00183 friend class GeomVertexArrayData; 00184 }; 00185 00186 PipelineCycler<CData> _cycler; 00187 typedef CycleDataReader<CData> CDReader; 00188 typedef CycleDataWriter<CData> CDWriter; 00189 typedef CycleDataStageReader<CData> CDStageReader; 00190 typedef CycleDataStageWriter<CData> CDStageWriter; 00191 00192 static SimpleLru _independent_lru; 00193 static SimpleLru _small_lru; 00194 static VertexDataBook _book; 00195 00196 public: 00197 static void register_with_read_factory(); 00198 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00199 PTA_uchar read_raw_data(BamReader *manager, DatagramIterator &source); 00200 virtual int complete_pointers(TypedWritable **plist, BamReader *manager); 00201 00202 virtual void finalize(BamReader *manager); 00203 00204 protected: 00205 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00206 void fillin(DatagramIterator &scan, BamReader *manager); 00207 00208 public: 00209 static TypeHandle get_class_type() { 00210 return _type_handle; 00211 } 00212 static void init_type() { 00213 CopyOnWriteObject::init_type(); 00214 register_type(_type_handle, "GeomVertexArrayData", 00215 CopyOnWriteObject::get_class_type()); 00216 CData::init_type(); 00217 } 00218 virtual TypeHandle get_type() const { 00219 return get_class_type(); 00220 } 00221 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00222 00223 private: 00224 static TypeHandle _type_handle; 00225 00226 friend class GeomCacheManager; 00227 friend class GeomVertexData; 00228 friend class PreparedGraphicsObjects; 00229 friend class GeomVertexArrayDataHandle; 00230 }; 00231 00232 //////////////////////////////////////////////////////////////////// 00233 // Class : GeomVertexArrayDataHandle 00234 // Description : This data object is returned by 00235 // GeomVertexArrayData::get_handle() or modify_handle(). 00236 // As long as it exists, the data is locked; when the 00237 // last of these destructs, the data is unlocked. 00238 // 00239 // Only one thread at a time may lock the data; other 00240 // threads attempting to lock the data will block. A 00241 // given thread may simultaneously lock the data 00242 // multiple times. 00243 // 00244 // This class serves in lieu of a pair of 00245 // GeomVertexArrayDataPipelineReader and 00246 // GeomVertexArrayDataPipelineWriter classes 00247 //////////////////////////////////////////////////////////////////// 00248 class EXPCL_PANDA_GOBJ GeomVertexArrayDataHandle : public ReferenceCount, public GeomEnums { 00249 private: 00250 INLINE GeomVertexArrayDataHandle(const GeomVertexArrayData *object, 00251 Thread *current_thread, 00252 const GeomVertexArrayData::CData *_cdata, 00253 bool writable); 00254 INLINE GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle &); 00255 INLINE void operator = (const GeomVertexArrayDataHandle &); 00256 00257 PUBLISHED: 00258 INLINE ~GeomVertexArrayDataHandle(); 00259 00260 public: 00261 ALLOC_DELETED_CHAIN_DECL(GeomVertexArrayDataHandle); 00262 00263 INLINE Thread *get_current_thread() const; 00264 00265 INLINE const unsigned char *get_read_pointer(bool force) const; 00266 unsigned char *get_write_pointer(); 00267 00268 PUBLISHED: 00269 INLINE const GeomVertexArrayData *get_object() const; 00270 INLINE GeomVertexArrayData *get_object(); 00271 00272 INLINE const GeomVertexArrayFormat *get_array_format() const; 00273 INLINE UsageHint get_usage_hint() const; 00274 00275 INLINE int get_num_rows() const; 00276 bool set_num_rows(int n); 00277 bool unclean_set_num_rows(int n); 00278 bool reserve_num_rows(int n); 00279 INLINE void clear_rows(); 00280 00281 INLINE int get_data_size_bytes() const; 00282 INLINE UpdateSeq get_modified() const; 00283 00284 INLINE bool request_resident() const; 00285 00286 void copy_data_from(const GeomVertexArrayDataHandle *other); 00287 void copy_subdata_from(size_t to_start, size_t to_size, 00288 const GeomVertexArrayDataHandle *other, 00289 size_t from_start, size_t from_size); 00290 00291 INLINE string get_data() const; 00292 void set_data(const string &data); 00293 INLINE string get_subdata(size_t start, size_t size) const; 00294 void set_subdata(size_t start, size_t size, const string &data); 00295 00296 INLINE void mark_used() const; 00297 00298 private: 00299 PT(GeomVertexArrayData) _object; 00300 Thread *_current_thread; 00301 GeomVertexArrayData::CData *_cdata; 00302 bool _writable; 00303 00304 public: 00305 static TypeHandle get_class_type() { 00306 return _type_handle; 00307 } 00308 static void init_type() { 00309 ReferenceCount::init_type(); 00310 register_type(_type_handle, "GeomVertexArrayDataHandle", 00311 ReferenceCount::get_class_type()); 00312 } 00313 00314 private: 00315 static TypeHandle _type_handle; 00316 00317 friend class GeomVertexArrayData; 00318 }; 00319 00320 INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj); 00321 00322 #include "geomVertexArrayData.I" 00323 00324 #endif