Panda3D
 All Classes Functions Variables Enumerations
renderAttribRegistry.cxx
1 // Filename: renderAttribRegistry.cxx
2 // Created by: drose (13Nov08)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "renderAttribRegistry.h"
16 #include "renderAttrib.h"
17 #include "renderState.h"
18 #include "deletedChain.h"
19 
20 RenderAttribRegistry *RenderAttribRegistry::_global_ptr;
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: RenderAttribRegistry::Constructor
24 // Access: Private
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 RenderAttribRegistry::
28 RenderAttribRegistry() {
29  ConfigVariableInt max_attribs
30  ("max-attribs", SlotMask::get_max_num_bits(),
31  PRC_DESC("This specifies the maximum number of different RenderAttrib "
32  "types that may be defined at runtime. Normally you should "
33  "never need to change this, but if the default value is too "
34  "low for the number of attribs that Panda actually defines, "
35  "you may need to raise this number."));
36 
37  // Assign this number once, at startup, and never change it again.
38  _max_slots = max((int)max_attribs, 1);
39  if (_max_slots > SlotMask::get_max_num_bits()) {
40  pgraph_cat->warning()
41  << "Value for max-attribs too large: cannot exceed "
43  << " in this build. To raise this limit, change the typedef "
44  << "for SlotMask in renderAttribRegistry.h and recompile.\n";
45 
46  _max_slots = SlotMask::get_max_num_bits();
47  }
48 
49  // Get a DeletedBufferChain to manage the arrays of RenderAttribs that are
50  // allocated within each RenderState object.
51  init_memory_hook();
52  _array_chain = memory_hook->get_deleted_chain(_max_slots * sizeof(RenderState::Attribute));
53 
54  // Reserve slot 0 for TypeHandle::none(), and for types that exceed
55  // max_slots.
56  RegistryNode node;
57  node._sort = 0;
58  node._make_default_func = NULL;
59  _registry.push_back(node);
60 }
61 
62 ////////////////////////////////////////////////////////////////////
63 // Function: RenderAttribRegistry::Destructor
64 // Access: Private
65 // Description:
66 ////////////////////////////////////////////////////////////////////
67 RenderAttribRegistry::
68 ~RenderAttribRegistry() {
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: RenderAttribRegistry::register_slot
73 // Access: Public
74 // Description: Adds the indicated TypeHandle to the registry, if it
75 // is not there already, and returns a unique slot
76 // number in the range 0 < slot < get_max_slots().
77 //
78 // The sort value is an arbitrary integer. In general,
79 // the RenderAttribs will be sorted in order from lowest
80 // sort value to highest sort value, when they are
81 // traversed via the get_num_sorted_slots() /
82 // get_sorted_slot() methods. This will be used to sort
83 // render states, so that heavier RenderAttribs are
84 // changed less frequently. In general, you should
85 // choose sort values such that the heavier
86 // RenderAttribs (that is, those which are more
87 // expensive to change) have lower sort values.
88 //
89 // The make_default_func pointer is a function that may
90 // be called to generate a default RenderAttrib to apply
91 // in the absence of any other attrib of this type.
92 //
93 // register_slot() is intended to be called at
94 // application start for each different RenderAttrib
95 // type in the system, to assign a different integer
96 // slot number to each one.
97 ////////////////////////////////////////////////////////////////////
99 register_slot(TypeHandle type_handle, int sort,
100  RenderAttribRegistry::MakeDefaultFunc *make_default_func) {
101  int type_index = type_handle.get_index();
102  while (type_index >= (int)_slots_by_type.size()) {
103  _slots_by_type.push_back(0);
104  }
105 
106  if (_slots_by_type[type_index] != 0) {
107  // This type has already been registered.
108  return _slots_by_type[type_index];
109  }
110 
111  int slot = (int)_registry.size();
112  if (slot >= _max_slots) {
113  pgraph_cat->error()
114  << "Too many registered RenderAttribs; not registering "
115  << type_handle << "\n";
116  nassertr(false, 0);
117  return 0;
118  }
119 
120  _slots_by_type[type_index] = slot;
121 
122  RegistryNode node;
123  node._type = type_handle;
124  node._sort = sort;
125  node._make_default_func = make_default_func;
126  _registry.push_back(node);
127 
128  _sorted_slots.push_back(slot);
129  ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
130 
131  return slot;
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: RenderAttribRegistry::set_slot_sort
136 // Access: Published
137 // Description: Changes the sort number associated with slot n.
138 ////////////////////////////////////////////////////////////////////
140 set_slot_sort(int slot, int sort) {
141  nassertv(slot >= 0 && slot < (int)_registry.size());
142  _registry[slot]._sort = sort;
143 
144  // Re-sort the slot list.
145  _sorted_slots.clear();
146  _sorted_slots.reserve(_registry.size() - 1);
147  for (int i = 1; i < (int)_registry.size(); ++i) {
148  _sorted_slots.push_back(i);
149  }
150  ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: RenderAttribRegistry::get_slot_default
155 // Access: Published
156 // Description: Returns the default RenderAttrib object associated
157 // with slot n. This is the attrib that should be
158 // applied in the absence of any other attrib of this
159 // type.
160 ////////////////////////////////////////////////////////////////////
162 get_slot_default(int slot) const {
163  nassertr(slot >= 0 && slot < (int)_registry.size(), 0);
164  return (*_registry[slot]._make_default_func)();
165 }
166 
167 ////////////////////////////////////////////////////////////////////
168 // Function: RenderAttribRegistry::init_global_ptr
169 // Access: Private, Static
170 // Description:
171 ////////////////////////////////////////////////////////////////////
172 void RenderAttribRegistry::
173 init_global_ptr() {
174  _global_ptr = new RenderAttribRegistry;
175 }
DeletedBufferChain * get_deleted_chain(size_t buffer_size)
Returns a pointer to a global DeletedBufferChain object suitable for allocating arrays of the indicat...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
int get_index() const
Returns the integer index associated with this TypeHandle.
Definition: typeHandle.I:253
static CONSTEXPR int get_max_num_bits()
int register_slot(TypeHandle type_handle, int sort, MakeDefaultFunc *make_default_func)
Adds the indicated TypeHandle to the registry, if it is not there already, and returns a unique slot ...
This class is used to associate each RenderAttrib with a different slot index at runtime, so we can store a list of RenderAttribs in the RenderState object, and very quickly look them up by type.
This is a convenience class to specialize ConfigVariable as an integer type.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
void set_slot_sort(int slot, int sort)
Changes the sort number associated with slot n.