renderAttribRegistry.cxx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 renderAttribRegistry.cxx
  10. * @author drose
  11. * @date 2008-11-13
  12. */
  13. #include "renderAttribRegistry.h"
  14. #include "renderAttrib.h"
  15. #include "renderState.h"
  16. #include "deletedChain.h"
  17. RenderAttribRegistry *RenderAttribRegistry::_global_ptr;
  18. /**
  19. *
  20. */
  21. RenderAttribRegistry::
  22. RenderAttribRegistry() {
  23. _registry.reserve(_max_slots);
  24. _sorted_slots.reserve(_max_slots);
  25. // Reserve slot 0 for TypeHandle::none(), and for types that exceed
  26. // max_slots.
  27. _registry.push_back(RegistryNode(TypeHandle::none(), 0, NULL));
  28. }
  29. /**
  30. *
  31. */
  32. RenderAttribRegistry::
  33. ~RenderAttribRegistry() {
  34. }
  35. /**
  36. * Adds the indicated TypeHandle to the registry, if it is not there already,
  37. * and returns a unique slot number in the range 0 < slot < get_max_slots().
  38. *
  39. * The sort value is an arbitrary integer. In general, the RenderAttribs will
  40. * be sorted in order from lowest sort value to highest sort value, when they
  41. * are traversed via the get_num_sorted_slots() get_sorted_slot() methods.
  42. * This will be used to sort render states, so that heavier RenderAttribs are
  43. * changed less frequently. In general, you should choose sort values such
  44. * that the heavier RenderAttribs (that is, those which are more expensive to
  45. * change) have lower sort values.
  46. *
  47. * The default_attrib pointer should be a newly created instance of this
  48. * attribute that represents the default state for this attribute.
  49. *
  50. * register_slot() is intended to be called at application start for each
  51. * different RenderAttrib type in the system, to assign a different integer
  52. * slot number to each one.
  53. */
  54. int RenderAttribRegistry::
  55. register_slot(TypeHandle type_handle, int sort, RenderAttrib *default_attrib) {
  56. // Sanity check; if this triggers, you either passed a wrong argument, or
  57. // you didn't use the type system correctly.
  58. nassertr(default_attrib->get_type() == type_handle, 0);
  59. int type_index = type_handle.get_index();
  60. while (type_index >= (int)_slots_by_type.size()) {
  61. _slots_by_type.push_back(0);
  62. }
  63. if (_slots_by_type[type_index] != 0) {
  64. // This type has already been registered.
  65. return _slots_by_type[type_index];
  66. }
  67. int slot = (int)_registry.size();
  68. if (slot >= _max_slots) {
  69. pgraph_cat->error()
  70. << "Too many registered RenderAttribs; not registering "
  71. << type_handle << "\n";
  72. nassertr(false, 0);
  73. return 0;
  74. }
  75. // Register the default attribute. We don't use return_unique and register
  76. // it even if the state cache is disabled, because we can't read the
  77. // state_cache config variable yet at this time. It probably doesn't hurt
  78. // to have these 32 entries around in the attrib cache.
  79. if (default_attrib != (RenderAttrib *)NULL) {
  80. default_attrib->calc_hash();
  81. if (default_attrib->_saved_entry == -1) {
  82. // If this attribute was already registered, something odd is going on.
  83. nassertr(RenderAttrib::_attribs->find(default_attrib) == -1, 0);
  84. default_attrib->_saved_entry =
  85. RenderAttrib::_attribs->store(default_attrib, nullptr);
  86. }
  87. // It effectively lives forever. Might as well make it official.
  88. default_attrib->local_object();
  89. }
  90. _slots_by_type[type_index] = slot;
  91. _registry.push_back(RegistryNode(type_handle, sort, default_attrib));
  92. _sorted_slots.push_back(slot);
  93. ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
  94. return slot;
  95. }
  96. /**
  97. * Changes the sort number associated with slot n.
  98. */
  99. void RenderAttribRegistry::
  100. set_slot_sort(int slot, int sort) {
  101. nassertv(slot >= 0 && slot < (int)_registry.size());
  102. _registry[slot]._sort = sort;
  103. // Re-sort the slot list.
  104. _sorted_slots.clear();
  105. for (int i = 1; i < (int)_registry.size(); ++i) {
  106. _sorted_slots.push_back(i);
  107. }
  108. ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
  109. }
  110. /**
  111. *
  112. */
  113. void RenderAttribRegistry::
  114. init_global_ptr() {
  115. _global_ptr = new RenderAttribRegistry;
  116. }