Panda3D
Loading...
Searching...
No Matches
renderState.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file renderState.h
10 * @author drose
11 * @date 2002-02-21
12 */
13
14#ifndef RENDERSTATE_H
15#define RENDERSTATE_H
16
17#include "pandabase.h"
18
19#include "renderAttrib.h"
21#include "pointerTo.h"
22#include "pvector.h"
23#include "updateSeq.h"
24#include "pStatCollector.h"
25#include "renderModeAttrib.h"
26#include "texMatrixAttrib.h"
27#include "geomMunger.h"
28#include "weakPointerTo.h"
29#include "lightReMutex.h"
30#include "lightMutex.h"
31#include "deletedChain.h"
32#include "simpleHashMap.h"
33#include "cacheStats.h"
35
36class FactoryParams;
37class ShaderAttrib;
38
39/**
40 * This represents a unique collection of RenderAttrib objects that correspond
41 * to a particular renderable state.
42 *
43 * You should not attempt to create or modify a RenderState object directly.
44 * Instead, call one of the make() functions to create one for you. And
45 * instead of modifying a RenderState object, create a new one.
46 */
47class EXPCL_PANDA_PGRAPH RenderState : public NodeCachedReferenceCount {
48protected:
50
51private:
52 RenderState(const RenderState &copy);
53
54public:
55 virtual ~RenderState();
56 ALLOC_DELETED_CHAIN(RenderState);
57
58 RenderState &operator = (const RenderState &copy) = delete;
59
61
62PUBLISHED:
63 int compare_to(const RenderState &other) const;
64 int compare_sort(const RenderState &other) const;
65 int compare_mask(const RenderState &other, SlotMask compare_mask) const;
66 INLINE size_t get_hash() const;
67
68 INLINE bool is_empty() const;
69
70 INLINE bool has_cull_callback() const;
71 bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
72
73 INLINE static CPT(RenderState) make_empty();
74 static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
75 static CPT(RenderState) make(const RenderAttrib *attrib1,
76 const RenderAttrib *attrib2, int override = 0);
77 static CPT(RenderState) make(const RenderAttrib *attrib1,
78 const RenderAttrib *attrib2,
79 const RenderAttrib *attrib3, int override = 0);
80 static CPT(RenderState) make(const RenderAttrib *attrib1,
81 const RenderAttrib *attrib2,
82 const RenderAttrib *attrib3,
83 const RenderAttrib *attrib4, int override = 0);
84 static CPT(RenderState) make(const RenderAttrib *attrib1,
85 const RenderAttrib *attrib2,
86 const RenderAttrib *attrib3,
87 const RenderAttrib *attrib4,
88 const RenderAttrib *attrib5, int override = 0);
89 static CPT(RenderState) make(const RenderAttrib * const *attrib,
90 int num_attribs, int override = 0);
91
92 CPT(RenderState) compose(const RenderState *other) const;
93 CPT(RenderState) invert_compose(const RenderState *other) const;
94
95 CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
96 CPT(RenderState) set_attrib(const RenderAttrib *attrib) const;
97 CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const;
98 INLINE CPT(RenderState) remove_attrib(TypeHandle type) const;
99 CPT(RenderState) remove_attrib(int slot) const;
100
101 CPT(RenderState) adjust_all_priorities(int adjustment) const;
102
103 INLINE bool has_attrib(TypeHandle type) const;
104 INLINE bool has_attrib(int slot) const;
105 INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
106 ALWAYS_INLINE const RenderAttrib *get_attrib(int slot) const;
107 INLINE const RenderAttrib *get_attrib_def(int slot) const;
108 INLINE int get_override(TypeHandle type) const;
109 INLINE int get_override(int slot) const;
110
111 MAKE_MAP_PROPERTY(attribs, has_attrib, get_attrib);
112
113 INLINE CPT(RenderState) get_unique() const;
114
115 virtual bool unref() const;
116
117 INLINE void cache_ref() const;
118 INLINE bool cache_unref() const;
119 INLINE void node_ref() const;
120 INLINE bool node_unref() const;
121
122 INLINE size_t get_composition_cache_num_entries() const;
123 INLINE size_t get_invert_composition_cache_num_entries() const;
124
125 INLINE size_t get_composition_cache_size() const;
126 INLINE const RenderState *get_composition_cache_source(size_t n) const;
127 INLINE const RenderState *get_composition_cache_result(size_t n) const;
128 INLINE size_t get_invert_composition_cache_size() const;
129 INLINE const RenderState *get_invert_composition_cache_source(size_t n) const;
130 INLINE const RenderState *get_invert_composition_cache_result(size_t n) const;
131 EXTENSION(PyObject *get_composition_cache() const);
132 EXTENSION(PyObject *get_invert_composition_cache() const);
133
134 void output(std::ostream &out) const;
135 void write(std::ostream &out, int indent_level) const;
136
137 static int get_max_priority();
138
139 static int get_num_states();
140 static int get_num_unused_states();
141 static int clear_cache();
142 static void clear_munger_cache();
143 static int garbage_collect();
144 static void list_cycles(std::ostream &out);
145 static void list_states(std::ostream &out);
146 static bool validate_states();
147 EXTENSION(static PyObject *get_states());
148 EXTENSION(static PyObject *get_unused_states());
149
150PUBLISHED:
151 // These methods are intended for use by low-level code, but they're also
152 // handy enough to expose to high-level users.
153 INLINE int get_draw_order() const;
154 INLINE int get_bin_index() const;
155 int get_geom_rendering(int geom_rendering) const;
156
157public:
158 static void bin_removed(int bin_index);
159
160 INLINE static void flush_level();
161
162#ifndef CPPPARSER
163 template<class AttribType>
164 INLINE bool get_attrib(const AttribType *&attrib) const;
165 template<class AttribType>
166 INLINE bool get_attrib(CPT(AttribType) &attrib) const;
167 template<class AttribType>
168 INLINE void get_attrib_def(const AttribType *&attrib) const;
169 template<class AttribType>
170 INLINE void get_attrib_def(CPT(AttribType) &attrib) const;
171#endif // CPPPARSER
172
173 INLINE void cache_ref_only() const;
174
175protected:
176 INLINE void cache_unref_only() const;
177
178private:
179 INLINE void check_hash() const;
180 bool validate_filled_slots() const;
181 INLINE bool do_cache_unref() const;
182 INLINE bool do_node_unref() const;
183 INLINE void calc_hash();
184 void do_calc_hash();
185
186 class CompositionCycleDescEntry {
187 public:
188 INLINE CompositionCycleDescEntry(const RenderState *obj,
189 const RenderState *result,
190 bool inverted);
191
192 const RenderState *_obj;
193 const RenderState *_result;
194 bool _inverted;
195 };
196 typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
197
198 static CPT(RenderState) return_new(RenderState *state);
199 static CPT(RenderState) return_unique(RenderState *state);
200 CPT(RenderState) do_compose(const RenderState *other) const;
201 CPT(RenderState) do_invert_compose(const RenderState *other) const;
202 void detect_and_break_cycles();
203 static bool r_detect_cycles(const RenderState *start_state,
204 const RenderState *current_state,
205 int length, UpdateSeq this_seq,
206 CompositionCycleDesc *cycle_desc);
207 static bool r_detect_reverse_cycles(const RenderState *start_state,
208 const RenderState *current_state,
209 int length, UpdateSeq this_seq,
210 CompositionCycleDesc *cycle_desc);
211
212 void release_new();
213 void remove_cache_pointers();
214
215 void determine_bin_index();
216 void determine_cull_callback();
217 void fill_default();
218
219 INLINE void set_destructing();
220 INLINE bool is_destructing() const;
221
222 INLINE void consider_update_pstats(int old_referenced_bits) const;
223 static void update_pstats(int old_referenced_bits, int new_referenced_bits);
224
225public:
226 static void init_states();
227
228 // If this state contains an "auto" ShaderAttrib, then an explicit
229 // ShaderAttrib will be synthesized by the runtime and stored here. I can't
230 // declare this as a ShaderAttrib because that would create a circular
231 // include-file dependency problem. Aaargh.
232 mutable CPT(RenderAttrib) _generated_shader;
233 mutable UpdateSeq _generated_shader_seq;
234
235private:
236 // This mutex protects _states. It also protects any modification to the
237 // cache, which is encoded in _composition_cache and
238 // _invert_composition_cache.
239 static LightReMutex *_states_lock;
241 static States *_states;
242 static const RenderState *_empty_state;
243
244 // This iterator records the entry corresponding to this RenderState object
245 // in the above global set. We keep the index around so we can remove it
246 // when the RenderState destructs.
247 int _saved_entry;
248
249 // This data structure manages the job of caching the composition of two
250 // RenderStates. It's complicated because we have to be sure to remove the
251 // entry if *either* of the input RenderStates destructs. To implement
252 // this, we always record Composition entries in pairs, one in each of the
253 // two involved RenderState objects.
254 class Composition {
255 public:
256 INLINE Composition();
257 INLINE Composition(const Composition &copy);
258
259 // _result is reference counted if and only if it is not the same pointer
260 // as this.
261 const RenderState *_result;
262 };
263
264 // The first element of the map is the object we compose with. This is not
265 // reference counted within this map; instead we store a companion pointer
266 // in the other object, and remove the references explicitly when either
267 // object destructs.
269 CompositionCache _composition_cache;
270 CompositionCache _invert_composition_cache;
271
272 // This is here to provide a quick cache of GSG + RenderState -> GeomMunger
273 // for the cull phase. It is here because it is faster to look up the GSG
274 // in the RenderState pointer than vice-versa, since there are likely to be
275 // far fewer GSG's than RenderStates. The code to manage this map lives in
276 // GraphicsStateGuardian::get_geom_munger().
277 typedef SimpleHashMap<size_t, PT(GeomMunger), size_t_hash> Mungers;
278 mutable Mungers _mungers;
279 mutable int _last_mi;
280
281 // Similarly, this is a cache of munged states. This map is managed by
282 // StateMunger::munge_state().
283 typedef SimpleHashMap<size_t, WCPT(RenderState), size_t_hash> MungedStates;
284 mutable MungedStates _munged_states;
285
286 // This is used to mark nodes as we visit them to detect cycles.
287 UpdateSeq _cycle_detect;
288 static UpdateSeq _last_cycle_detect;
289
290 // This keeps track of our current position through the garbage collection
291 // cycle.
292 static size_t _garbage_index;
293
294 static PStatCollector _cache_update_pcollector;
295 static PStatCollector _garbage_collect_pcollector;
296 static PStatCollector _state_compose_pcollector;
297 static PStatCollector _state_invert_pcollector;
298 static PStatCollector _state_break_cycles_pcollector;
299 static PStatCollector _state_validate_pcollector;
300
301 static PStatCollector _node_counter;
302 static PStatCollector _cache_counter;
303
304private:
305 // This is the actual data within the RenderState: a set of max_slots
306 // RenderAttribs.
307 class Attribute {
308 public:
309 INLINE Attribute(const RenderAttrib *attrib, int override);
310 INLINE Attribute(int override = 0);
311 INLINE Attribute(const Attribute &copy);
312 INLINE void operator = (const Attribute &copy);
313 INLINE void set(const RenderAttrib *attrib, int override);
314 INLINE int compare_to(const Attribute &other) const;
315
316 CPT(RenderAttrib) _attrib;
317 int _override;
318 };
319 Attribute _attributes[RenderAttribRegistry::_max_slots];
320
321 // We also store a bitmask of the non-NULL attributes in the above array.
322 // This is redundant, but it is a useful cache.
323 SlotMask _filled_slots;
324
325 // We cache the index to the associated CullBin, if there happens to be a
326 // CullBinAttrib in the state.
327 int _bin_index;
328 int _draw_order;
329 size_t _hash;
330
331 enum Flags {
332 F_checked_bin_index = 0x000001,
333 F_checked_cull_callback = 0x000002,
334 F_has_cull_callback = 0x000004,
335 F_is_destructing = 0x000008,
336 F_hash_known = 0x000010,
337 };
338 unsigned int _flags;
339
340 vector_int *_read_overrides; // Only used during bam reading.
341
342 // This mutex protects _flags, and all of the above computed values.
343 LightMutex _lock;
344
345 static CacheStats _cache_stats;
346
347public:
348 static void register_with_read_factory();
349 virtual void write_datagram(BamWriter *manager, Datagram &dg);
350 virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
351 static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
352 virtual void finalize(BamReader *manager);
353
354protected:
355 static TypedWritable *make_from_bam(const FactoryParams &params);
356 void fillin(DatagramIterator &scan, BamReader *manager);
357
358public:
359 static TypeHandle get_class_type() {
360 return _type_handle;
361 }
362 static void init_type() {
363 NodeCachedReferenceCount::init_type();
364 register_type(_type_handle, "RenderState",
365 NodeCachedReferenceCount::get_class_type());
366 }
367 virtual TypeHandle get_type() const {
368 return get_class_type();
369 }
370 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
371
372private:
373 static TypeHandle _type_handle;
374
375 friend class GraphicsStateGuardian;
376 friend class RenderAttribRegistry;
377 friend class Extension<RenderState>;
378 friend class ShaderGenerator;
379 friend class StateMunger;
380};
381
382// We can safely redefine this as a no-op.
383template<>
384INLINE void PointerToBase<RenderState>::update_type(To *ptr) {}
385
386INLINE std::ostream &operator << (std::ostream &out, const RenderState &state) {
387 state.output(out);
388 return out;
389}
390
391#include "renderState.I"
392
393#endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
This is used to track the utilization of the TransformState and RenderState caches,...
Definition cacheStats.h:25
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
bool cache_unref() const
Explicitly decrements the cache reference count and the normal reference count simultaneously.
void cache_ref_only() const
Decrements the cache reference count without affecting the normal reference count.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
The default class template does not define any methods.
Definition extension.h:34
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition geomMunger.h:50
Encapsulates all the communication with a particular instance of a given rendering backend.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition lightMutex.h:41
A lightweight reentrant mutex.
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
void node_ref() const
Explicitly increments the reference count.
A lightweight class that represents a single element that may be timed and/or counted via stats.
This is the base class for PointerTo and ConstPointerTo.
This class is used to associate each RenderAttrib with a different slot index at runtime,...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition renderState.h:47
virtual bool unref() const
Explicitly decrements the reference count.
This template class implements an unordered map of keys to data, implemented as a hashtable.
This is just a simple derivative of GeomMunger that adds the ability to munge states.
Definition stateMunger.h:26
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
An STL function object class, this is intended to be used on any ordered collection of class objects ...
This is the default hash_compare class, which assumes the Key is a size_t value or can be implicitly ...
This is our own Panda specialization on the default STL list.
Definition plist.h:35
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.