00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef RENDERSTATE_H
00016 #define RENDERSTATE_H
00017
00018 #include "pandabase.h"
00019
00020 #include "renderAttrib.h"
00021 #include "nodeCachedReferenceCount.h"
00022 #include "pointerTo.h"
00023 #include "pvector.h"
00024 #include "updateSeq.h"
00025 #include "pStatCollector.h"
00026 #include "renderModeAttrib.h"
00027 #include "texMatrixAttrib.h"
00028 #include "geomMunger.h"
00029 #include "weakPointerTo.h"
00030 #include "lightReMutex.h"
00031 #include "lightMutex.h"
00032 #include "deletedChain.h"
00033 #include "simpleHashMap.h"
00034 #include "cacheStats.h"
00035 #include "renderAttribRegistry.h"
00036
00037 class GraphicsStateGuardianBase;
00038 class FactoryParams;
00039 class ShaderAttrib;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 class EXPCL_PANDA_PGRAPH RenderState : public NodeCachedReferenceCount {
00054 protected:
00055 RenderState();
00056
00057 private:
00058 RenderState(const RenderState ©);
00059 void operator = (const RenderState ©);
00060
00061 public:
00062 virtual ~RenderState();
00063 ALLOC_DELETED_CHAIN(RenderState);
00064
00065 typedef RenderAttribRegistry::SlotMask SlotMask;
00066
00067 PUBLISHED:
00068 int compare_to(const RenderState &other) const;
00069 int compare_sort(const RenderState &other) const;
00070 INLINE size_t get_hash() const;
00071
00072 INLINE bool is_empty() const;
00073
00074 INLINE bool has_cull_callback() const;
00075 bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
00076
00077 static CPT(RenderState) make_empty();
00078 static CPT(RenderState) make_full_default();
00079 static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
00080 static CPT(RenderState) make(const RenderAttrib *attrib1,
00081 const RenderAttrib *attrib2, int override = 0);
00082 static CPT(RenderState) make(const RenderAttrib *attrib1,
00083 const RenderAttrib *attrib2,
00084 const RenderAttrib *attrib3, int override = 0);
00085 static CPT(RenderState) make(const RenderAttrib *attrib1,
00086 const RenderAttrib *attrib2,
00087 const RenderAttrib *attrib3,
00088 const RenderAttrib *attrib4, int override = 0);
00089 static CPT(RenderState) make(const RenderAttrib * const *attrib,
00090 int num_attribs, int override = 0);
00091
00092 CPT(RenderState) compose(const RenderState *other) const;
00093 CPT(RenderState) invert_compose(const RenderState *other) const;
00094
00095 CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
00096 CPT(RenderState) set_attrib(const RenderAttrib *attrib) const;
00097 CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const;
00098 INLINE CPT(RenderState) remove_attrib(TypeHandle type) const;
00099 CPT(RenderState) remove_attrib(int slot) const;
00100
00101 CPT(RenderState) adjust_all_priorities(int adjustment) const;
00102
00103 INLINE bool has_attrib(TypeHandle type) const;
00104 INLINE bool has_attrib(int slot) const;
00105 INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
00106 INLINE const RenderAttrib *get_attrib(int slot) const;
00107 INLINE const RenderAttrib *get_attrib_def(int slot) const;
00108 INLINE int get_override(TypeHandle type) const;
00109 INLINE int get_override(int slot) const;
00110
00111 INLINE CPT(RenderState) get_unique() const;
00112
00113 virtual bool unref() const;
00114
00115 INLINE void cache_ref() const;
00116 INLINE bool cache_unref() const;
00117 INLINE void node_ref() const;
00118 INLINE bool node_unref() const;
00119
00120 INLINE int get_composition_cache_num_entries() const;
00121 INLINE int get_invert_composition_cache_num_entries() const;
00122
00123 INLINE int get_composition_cache_size() const;
00124 INLINE const RenderState *get_composition_cache_source(int n) const;
00125 INLINE const RenderState *get_composition_cache_result(int n) const;
00126 INLINE int get_invert_composition_cache_size() const;
00127 INLINE const RenderState *get_invert_composition_cache_source(int n) const;
00128 INLINE const RenderState *get_invert_composition_cache_result(int n) const;
00129 #ifdef HAVE_PYTHON
00130 PyObject *get_composition_cache() const;
00131 PyObject *get_invert_composition_cache() const;
00132 #endif // HAVE_PYTHON
00133
00134 const RenderState *get_auto_shader_state() const;
00135
00136 void output(ostream &out) const;
00137 void write(ostream &out, int indent_level) const;
00138
00139 static int get_max_priority();
00140
00141 static int get_num_states();
00142 static int get_num_unused_states();
00143 static int clear_cache();
00144 static void clear_munger_cache();
00145 static int garbage_collect();
00146 static void list_cycles(ostream &out);
00147 static void list_states(ostream &out);
00148 static bool validate_states();
00149 #ifdef HAVE_PYTHON
00150 static PyObject *get_states();
00151 #endif // HAVE_PYTHON
00152
00153 PUBLISHED:
00154
00155
00156 INLINE int get_draw_order() const;
00157 INLINE int get_bin_index() const;
00158 int get_geom_rendering(int geom_rendering) const;
00159
00160 public:
00161 static void bin_removed(int bin_index);
00162
00163 INLINE static void flush_level();
00164
00165 private:
00166 INLINE void check_hash() const;
00167 bool validate_filled_slots() const;
00168 INLINE bool do_cache_unref() const;
00169 INLINE bool do_node_unref() const;
00170 INLINE void calc_hash();
00171 void do_calc_hash();
00172 void assign_auto_shader_state();
00173 CPT(RenderState) do_calc_auto_shader_state();
00174
00175 class CompositionCycleDescEntry {
00176 public:
00177 INLINE CompositionCycleDescEntry(const RenderState *obj,
00178 const RenderState *result,
00179 bool inverted);
00180
00181 const RenderState *_obj;
00182 const RenderState *_result;
00183 bool _inverted;
00184 };
00185 typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
00186
00187 static CPT(RenderState) return_new(RenderState *state);
00188 static CPT(RenderState) return_unique(RenderState *state);
00189 CPT(RenderState) do_compose(const RenderState *other) const;
00190 CPT(RenderState) do_invert_compose(const RenderState *other) const;
00191 void detect_and_break_cycles();
00192 static bool r_detect_cycles(const RenderState *start_state,
00193 const RenderState *current_state,
00194 int length, UpdateSeq this_seq,
00195 CompositionCycleDesc *cycle_desc);
00196 static bool r_detect_reverse_cycles(const RenderState *start_state,
00197 const RenderState *current_state,
00198 int length, UpdateSeq this_seq,
00199 CompositionCycleDesc *cycle_desc);
00200
00201 void release_new();
00202 void remove_cache_pointers();
00203
00204 void determine_bin_index();
00205 void determine_cull_callback();
00206 void fill_default();
00207
00208 INLINE void set_destructing();
00209 INLINE bool is_destructing() const;
00210
00211 INLINE void consider_update_pstats(int old_referenced_bits) const;
00212 static void update_pstats(int old_referenced_bits, int new_referenced_bits);
00213
00214 public:
00215 static void init_states();
00216
00217
00218
00219
00220
00221 CPT(RenderAttrib) _generated_shader;
00222
00223 private:
00224
00225
00226
00227 static LightReMutex *_states_lock;
00228 class Empty {
00229 };
00230 typedef SimpleHashMap<const RenderState *, Empty, indirect_compare_to_hash<const RenderState *> > States;
00231 static States *_states;
00232 static CPT(RenderState) _empty_state;
00233 static CPT(RenderState) _full_default_state;
00234
00235
00236
00237
00238 int _saved_entry;
00239
00240
00241
00242
00243
00244
00245 class Composition {
00246 public:
00247 INLINE Composition();
00248 INLINE Composition(const Composition ©);
00249
00250
00251
00252 const RenderState *_result;
00253 };
00254
00255
00256
00257
00258
00259 typedef SimpleHashMap<const RenderState *, Composition, pointer_hash> CompositionCache;
00260 CompositionCache _composition_cache;
00261 CompositionCache _invert_composition_cache;
00262
00263
00264
00265
00266
00267
00268
00269 typedef pmap<WCPT(GraphicsStateGuardianBase), PT(GeomMunger) > Mungers;
00270 Mungers _mungers;
00271 Mungers::const_iterator _last_mi;
00272
00273
00274 UpdateSeq _cycle_detect;
00275 static UpdateSeq _last_cycle_detect;
00276
00277
00278
00279 static int _garbage_index;
00280
00281 static PStatCollector _cache_update_pcollector;
00282 static PStatCollector _garbage_collect_pcollector;
00283 static PStatCollector _state_compose_pcollector;
00284 static PStatCollector _state_invert_pcollector;
00285 static PStatCollector _state_break_cycles_pcollector;
00286 static PStatCollector _state_validate_pcollector;
00287
00288 static PStatCollector _node_counter;
00289 static PStatCollector _cache_counter;
00290
00291 private:
00292
00293
00294 class Attribute {
00295 public:
00296 INLINE Attribute(const RenderAttrib *attrib, int override);
00297 INLINE Attribute(int override = 0);
00298 INLINE Attribute(const Attribute ©);
00299 INLINE void operator = (const Attribute ©);
00300 INLINE void set(const RenderAttrib *attrib, int override);
00301 INLINE int compare_to(const Attribute &other) const;
00302
00303 CPT(RenderAttrib) _attrib;
00304 int _override;
00305 };
00306 Attribute *_attributes;
00307
00308
00309
00310 SlotMask _filled_slots;
00311
00312
00313
00314 int _bin_index;
00315 int _draw_order;
00316 size_t _hash;
00317
00318 const RenderState *_auto_shader_state;
00319
00320 enum Flags {
00321 F_checked_bin_index = 0x000001,
00322 F_checked_cull_callback = 0x000002,
00323 F_has_cull_callback = 0x000004,
00324 F_is_destructing = 0x000008,
00325 F_hash_known = 0x000010,
00326 };
00327 unsigned int _flags;
00328
00329 vector_int *_read_overrides;
00330
00331
00332 LightMutex _lock;
00333
00334 static CacheStats _cache_stats;
00335
00336 public:
00337 static void register_with_read_factory();
00338 virtual void write_datagram(BamWriter *manager, Datagram &dg);
00339 virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
00340 static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
00341 virtual void finalize(BamReader *manager);
00342
00343 protected:
00344 static TypedWritable *make_from_bam(const FactoryParams ¶ms);
00345 void fillin(DatagramIterator &scan, BamReader *manager);
00346
00347 public:
00348 static TypeHandle get_class_type() {
00349 return _type_handle;
00350 }
00351 static void init_type() {
00352 NodeCachedReferenceCount::init_type();
00353 register_type(_type_handle, "RenderState",
00354 NodeCachedReferenceCount::get_class_type());
00355 }
00356 virtual TypeHandle get_type() const {
00357 return get_class_type();
00358 }
00359 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00360
00361 private:
00362 static TypeHandle _type_handle;
00363
00364 friend class GraphicsStateGuardian;
00365 friend class RenderAttribRegistry;
00366 };
00367
00368 INLINE ostream &operator << (ostream &out, const RenderState &state) {
00369 state.output(out);
00370 return out;
00371 }
00372
00373 #include "renderState.I"
00374
00375 #endif
00376