renderState.cxx 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311
  1. // Filename: renderState.cxx
  2. // Created by: drose (21Feb02)
  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. #include "renderState.h"
  15. #include "transparencyAttrib.h"
  16. #include "cullBinAttrib.h"
  17. #include "cullBinManager.h"
  18. #include "fogAttrib.h"
  19. #include "clipPlaneAttrib.h"
  20. #include "scissorAttrib.h"
  21. #include "transparencyAttrib.h"
  22. #include "colorAttrib.h"
  23. #include "colorScaleAttrib.h"
  24. #include "textureAttrib.h"
  25. #include "texGenAttrib.h"
  26. #include "shaderAttrib.h"
  27. #include "pStatTimer.h"
  28. #include "config_pgraph.h"
  29. #include "bamReader.h"
  30. #include "bamWriter.h"
  31. #include "datagramIterator.h"
  32. #include "indent.h"
  33. #include "compareTo.h"
  34. #include "lightReMutexHolder.h"
  35. #include "lightMutexHolder.h"
  36. #include "thread.h"
  37. #include "renderAttribRegistry.h"
  38. #include "py_panda.h"
  39. LightReMutex *RenderState::_states_lock = NULL;
  40. RenderState::States *RenderState::_states = NULL;
  41. const RenderState *RenderState::_empty_state = NULL;
  42. UpdateSeq RenderState::_last_cycle_detect;
  43. int RenderState::_garbage_index = 0;
  44. PStatCollector RenderState::_cache_update_pcollector("*:State Cache:Update");
  45. PStatCollector RenderState::_garbage_collect_pcollector("*:State Cache:Garbage Collect");
  46. PStatCollector RenderState::_state_compose_pcollector("*:State Cache:Compose State");
  47. PStatCollector RenderState::_state_invert_pcollector("*:State Cache:Invert State");
  48. PStatCollector RenderState::_node_counter("RenderStates:On nodes");
  49. PStatCollector RenderState::_cache_counter("RenderStates:Cached");
  50. PStatCollector RenderState::_state_break_cycles_pcollector("*:State Cache:Break Cycles");
  51. PStatCollector RenderState::_state_validate_pcollector("*:State Cache:Validate");
  52. CacheStats RenderState::_cache_stats;
  53. TypeHandle RenderState::_type_handle;
  54. ////////////////////////////////////////////////////////////////////
  55. // Function: RenderState::Constructor
  56. // Access: Protected
  57. // Description: Actually, this could be a private constructor, since
  58. // no one inherits from RenderState, but gcc gives us a
  59. // spurious warning if all constructors are private.
  60. ////////////////////////////////////////////////////////////////////
  61. RenderState::
  62. RenderState() :
  63. _flags(0),
  64. _auto_shader_state(NULL),
  65. _lock("RenderState")
  66. {
  67. if (_states == (States *)NULL) {
  68. init_states();
  69. }
  70. _saved_entry = -1;
  71. _last_mi = -1;
  72. _cache_stats.add_num_states(1);
  73. _read_overrides = NULL;
  74. _generated_shader = NULL;
  75. }
  76. ////////////////////////////////////////////////////////////////////
  77. // Function: RenderState::Copy Constructor
  78. // Access: Private
  79. // Description: RenderStates are only meant to be copied internally.
  80. ////////////////////////////////////////////////////////////////////
  81. RenderState::
  82. RenderState(const RenderState &copy) :
  83. _filled_slots(copy._filled_slots),
  84. _flags(0),
  85. _auto_shader_state(NULL),
  86. _lock("RenderState")
  87. {
  88. // Copy over the attributes.
  89. for (int i = 0; i < RenderAttribRegistry::_max_slots; ++i) {
  90. _attributes[i] = copy._attributes[i];
  91. }
  92. _saved_entry = -1;
  93. _last_mi = -1;
  94. _cache_stats.add_num_states(1);
  95. _read_overrides = NULL;
  96. _generated_shader = NULL;
  97. }
  98. ////////////////////////////////////////////////////////////////////
  99. // Function: RenderState::Copy Assignment Operator
  100. // Access: Private
  101. // Description: RenderStates are not meant to be copied.
  102. ////////////////////////////////////////////////////////////////////
  103. void RenderState::
  104. operator = (const RenderState &) {
  105. nassertv(false);
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: RenderState::Destructor
  109. // Access: Public, Virtual
  110. // Description: The destructor is responsible for removing the
  111. // RenderState from the global set if it is there.
  112. ////////////////////////////////////////////////////////////////////
  113. RenderState::
  114. ~RenderState() {
  115. // We'd better not call the destructor twice on a particular object.
  116. nassertv(!is_destructing());
  117. set_destructing();
  118. LightReMutexHolder holder(*_states_lock);
  119. // unref() should have cleared these.
  120. nassertv(_saved_entry == -1);
  121. nassertv(_composition_cache.is_empty() && _invert_composition_cache.is_empty());
  122. // Make sure the _auto_shader_state cache pointer is cleared.
  123. if (_auto_shader_state != (const RenderState *)NULL) {
  124. if (_auto_shader_state != this) {
  125. cache_unref_delete(_auto_shader_state);
  126. }
  127. _auto_shader_state = NULL;
  128. }
  129. // If this was true at the beginning of the destructor, but is no
  130. // longer true now, probably we've been double-deleted.
  131. nassertv(get_ref_count() == 0);
  132. _cache_stats.add_num_states(-1);
  133. }
  134. ////////////////////////////////////////////////////////////////////
  135. // Function: RenderState::compare_to
  136. // Access: Published
  137. // Description: Provides an arbitrary ordering among all unique
  138. // RenderStates, so we can store the essentially
  139. // different ones in a big set and throw away the rest.
  140. //
  141. // This method is not needed outside of the RenderState
  142. // class because all equivalent RenderState objects are
  143. // guaranteed to share the same pointer; thus, a pointer
  144. // comparison is always sufficient.
  145. ////////////////////////////////////////////////////////////////////
  146. int RenderState::
  147. compare_to(const RenderState &other) const {
  148. SlotMask mask = _filled_slots | other._filled_slots;
  149. int slot = mask.get_lowest_on_bit();
  150. while (slot >= 0) {
  151. int result = _attributes[slot].compare_to(other._attributes[slot]);
  152. if (result != 0) {
  153. return result;
  154. }
  155. mask.clear_bit(slot);
  156. slot = mask.get_lowest_on_bit();
  157. }
  158. return 0;
  159. }
  160. ////////////////////////////////////////////////////////////////////
  161. // Function: RenderState::compare_sort
  162. // Access: Published
  163. // Description: Returns -1, 0, or 1 according to the relative sorting
  164. // of these two RenderStates, with regards to rendering
  165. // performance, so that "heavier" RenderAttribs (as
  166. // defined by RenderAttribRegistry::get_slot_sort()) are
  167. // more likely to be grouped together. This is not
  168. // related to the sorting order defined by compare_to.
  169. ////////////////////////////////////////////////////////////////////
  170. int RenderState::
  171. compare_sort(const RenderState &other) const {
  172. if (this == &other) {
  173. // Trivial case.
  174. return 0;
  175. }
  176. RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
  177. int num_sorted_slots = reg->get_num_sorted_slots();
  178. for (int n = 0; n < num_sorted_slots; ++n) {
  179. int slot = reg->get_sorted_slot(n);
  180. nassertr((_attributes[slot]._attrib != NULL) == _filled_slots.get_bit(slot), 0);
  181. const RenderAttrib *a = _attributes[slot]._attrib;
  182. const RenderAttrib *b = other._attributes[slot]._attrib;
  183. if (a != b) {
  184. return a < b ? -1 : 1;
  185. }
  186. }
  187. return 0;
  188. }
  189. ////////////////////////////////////////////////////////////////////
  190. // Function: RenderState::compare_mask
  191. // Access: Published
  192. // Description: This version of compare_to takes a slot mask that
  193. // indicates which attributes to include in the
  194. // comparison. Unlike compare_to, this method
  195. // compares the attributes by pointer.
  196. ////////////////////////////////////////////////////////////////////
  197. int RenderState::
  198. compare_mask(const RenderState &other, SlotMask compare_mask) const {
  199. SlotMask mask = (_filled_slots | other._filled_slots) & compare_mask;
  200. int slot = mask.get_lowest_on_bit();
  201. while (slot >= 0) {
  202. const RenderAttrib *a = _attributes[slot]._attrib;
  203. const RenderAttrib *b = other._attributes[slot]._attrib;
  204. if (a != b) {
  205. return a < b ? -1 : 1;
  206. }
  207. mask.clear_bit(slot);
  208. slot = mask.get_lowest_on_bit();
  209. }
  210. return 0;
  211. }
  212. ////////////////////////////////////////////////////////////////////
  213. // Function: RenderState::cull_callback
  214. // Access: Published
  215. // Description: Calls cull_callback() on each attrib. If any attrib
  216. // returns false, interrupts the list and returns false
  217. // immediately; otherwise, completes the list and
  218. // returns true.
  219. ////////////////////////////////////////////////////////////////////
  220. bool RenderState::
  221. cull_callback(CullTraverser *trav, const CullTraverserData &data) const {
  222. SlotMask mask = _filled_slots;
  223. int slot = mask.get_lowest_on_bit();
  224. while (slot >= 0) {
  225. const Attribute &attrib = _attributes[slot];
  226. nassertr(attrib._attrib != NULL, false);
  227. if (!attrib._attrib->cull_callback(trav, data)) {
  228. return false;
  229. }
  230. mask.clear_bit(slot);
  231. slot = mask.get_lowest_on_bit();
  232. }
  233. return true;
  234. }
  235. ////////////////////////////////////////////////////////////////////
  236. // Function: RenderState::make
  237. // Access: Published, Static
  238. // Description: Returns a RenderState with one attribute set.
  239. ////////////////////////////////////////////////////////////////////
  240. CPT(RenderState) RenderState::
  241. make(const RenderAttrib *attrib, int override) {
  242. RenderState *state = new RenderState;
  243. int slot = attrib->get_slot();
  244. state->_attributes[slot].set(attrib, override);
  245. state->_filled_slots.set_bit(slot);
  246. return return_new(state);
  247. }
  248. ////////////////////////////////////////////////////////////////////
  249. // Function: RenderState::make
  250. // Access: Published, Static
  251. // Description: Returns a RenderState with two attributes set.
  252. ////////////////////////////////////////////////////////////////////
  253. CPT(RenderState) RenderState::
  254. make(const RenderAttrib *attrib1,
  255. const RenderAttrib *attrib2, int override) {
  256. RenderState *state = new RenderState;
  257. state->_attributes[attrib1->get_slot()].set(attrib1, override);
  258. state->_attributes[attrib2->get_slot()].set(attrib2, override);
  259. state->_filled_slots.set_bit(attrib1->get_slot());
  260. state->_filled_slots.set_bit(attrib2->get_slot());
  261. return return_new(state);
  262. }
  263. ////////////////////////////////////////////////////////////////////
  264. // Function: RenderState::make
  265. // Access: Published, Static
  266. // Description: Returns a RenderState with three attributes set.
  267. ////////////////////////////////////////////////////////////////////
  268. CPT(RenderState) RenderState::
  269. make(const RenderAttrib *attrib1,
  270. const RenderAttrib *attrib2,
  271. const RenderAttrib *attrib3, int override) {
  272. RenderState *state = new RenderState;
  273. state->_attributes[attrib1->get_slot()].set(attrib1, override);
  274. state->_attributes[attrib2->get_slot()].set(attrib2, override);
  275. state->_attributes[attrib3->get_slot()].set(attrib3, override);
  276. state->_filled_slots.set_bit(attrib1->get_slot());
  277. state->_filled_slots.set_bit(attrib2->get_slot());
  278. state->_filled_slots.set_bit(attrib3->get_slot());
  279. return return_new(state);
  280. }
  281. ////////////////////////////////////////////////////////////////////
  282. // Function: RenderState::make
  283. // Access: Published, Static
  284. // Description: Returns a RenderState with four attributes set.
  285. ////////////////////////////////////////////////////////////////////
  286. CPT(RenderState) RenderState::
  287. make(const RenderAttrib *attrib1,
  288. const RenderAttrib *attrib2,
  289. const RenderAttrib *attrib3,
  290. const RenderAttrib *attrib4, int override) {
  291. RenderState *state = new RenderState;
  292. state->_attributes[attrib1->get_slot()].set(attrib1, override);
  293. state->_attributes[attrib2->get_slot()].set(attrib2, override);
  294. state->_attributes[attrib3->get_slot()].set(attrib3, override);
  295. state->_attributes[attrib4->get_slot()].set(attrib4, override);
  296. state->_filled_slots.set_bit(attrib1->get_slot());
  297. state->_filled_slots.set_bit(attrib2->get_slot());
  298. state->_filled_slots.set_bit(attrib3->get_slot());
  299. state->_filled_slots.set_bit(attrib4->get_slot());
  300. return return_new(state);
  301. }
  302. ////////////////////////////////////////////////////////////////////
  303. // Function: RenderState::make
  304. // Access: Published, Static
  305. // Description: Returns a RenderState with n attributes set.
  306. ////////////////////////////////////////////////////////////////////
  307. CPT(RenderState) RenderState::
  308. make(const RenderAttrib * const *attrib, int num_attribs, int override) {
  309. if (num_attribs == 0) {
  310. return _empty_state;
  311. }
  312. RenderState *state = new RenderState;
  313. for (int i = 0; i < num_attribs; i++) {
  314. int slot = attrib[i]->get_slot();
  315. state->_attributes[slot].set(attrib[i], override);
  316. state->_filled_slots.set_bit(slot);
  317. }
  318. return return_new(state);
  319. }
  320. ////////////////////////////////////////////////////////////////////
  321. // Function: RenderState::compose
  322. // Access: Published
  323. // Description: Returns a new RenderState object that represents the
  324. // composition of this state with the other state.
  325. //
  326. // The result of this operation is cached, and will be
  327. // retained as long as both this RenderState object and
  328. // the other RenderState object continue to exist.
  329. // Should one of them destruct, the cached entry will be
  330. // removed, and its pointer will be allowed to destruct
  331. // as well.
  332. ////////////////////////////////////////////////////////////////////
  333. CPT(RenderState) RenderState::
  334. compose(const RenderState *other) const {
  335. // This method isn't strictly const, because it updates the cache,
  336. // but we pretend that it is because it's only a cache which is
  337. // transparent to the rest of the interface.
  338. // We handle empty state (identity) as a trivial special case.
  339. if (is_empty()) {
  340. return other;
  341. }
  342. if (other->is_empty()) {
  343. return this;
  344. }
  345. if (!state_cache) {
  346. return do_compose(other);
  347. }
  348. LightReMutexHolder holder(*_states_lock);
  349. // Is this composition already cached?
  350. int index = _composition_cache.find(other);
  351. if (index != -1) {
  352. Composition &comp = ((RenderState *)this)->_composition_cache.modify_data(index);
  353. if (comp._result == (const RenderState *)NULL) {
  354. // Well, it wasn't cached already, but we already had an entry
  355. // (probably created for the reverse direction), so use the same
  356. // entry to store the new result.
  357. CPT(RenderState) result = do_compose(other);
  358. comp._result = result;
  359. if (result != (const RenderState *)this) {
  360. // See the comments below about the need to up the reference
  361. // count only when the result is not the same as this.
  362. result->cache_ref();
  363. }
  364. }
  365. // Here's the cache!
  366. _cache_stats.inc_hits();
  367. return comp._result;
  368. }
  369. _cache_stats.inc_misses();
  370. // We need to make a new cache entry, both in this object and in the
  371. // other object. We make both records so the other RenderState
  372. // object will know to delete the entry from this object when it
  373. // destructs, and vice-versa.
  374. // The cache entry in this object is the only one that indicates the
  375. // result; the other will be NULL for now.
  376. CPT(RenderState) result = do_compose(other);
  377. _cache_stats.add_total_size(1);
  378. _cache_stats.inc_adds(_composition_cache.get_size() == 0);
  379. ((RenderState *)this)->_composition_cache[other]._result = result;
  380. if (other != this) {
  381. _cache_stats.add_total_size(1);
  382. _cache_stats.inc_adds(other->_composition_cache.get_size() == 0);
  383. ((RenderState *)other)->_composition_cache[this]._result = NULL;
  384. }
  385. if (result != (const RenderState *)this) {
  386. // If the result of compose() is something other than this,
  387. // explicitly increment the reference count. We have to be sure
  388. // to decrement it again later, when the composition entry is
  389. // removed from the cache.
  390. result->cache_ref();
  391. // (If the result was just this again, we still store the
  392. // result, but we don't increment the reference count, since
  393. // that would be a self-referential leak.)
  394. }
  395. _cache_stats.maybe_report("RenderState");
  396. return result;
  397. }
  398. ////////////////////////////////////////////////////////////////////
  399. // Function: RenderState::invert_compose
  400. // Access: Published
  401. // Description: Returns a new RenderState object that represents the
  402. // composition of this state's inverse with the other
  403. // state.
  404. //
  405. // This is similar to compose(), but is particularly
  406. // useful for computing the relative state of a node as
  407. // viewed from some other node.
  408. ////////////////////////////////////////////////////////////////////
  409. CPT(RenderState) RenderState::
  410. invert_compose(const RenderState *other) const {
  411. // This method isn't strictly const, because it updates the cache,
  412. // but we pretend that it is because it's only a cache which is
  413. // transparent to the rest of the interface.
  414. // We handle empty state (identity) as a trivial special case.
  415. if (is_empty()) {
  416. return other;
  417. }
  418. // Unlike compose(), the case of other->is_empty() is not quite as
  419. // trivial for invert_compose().
  420. if (other == this) {
  421. // a->invert_compose(a) always produces identity.
  422. return _empty_state;
  423. }
  424. if (!state_cache) {
  425. return do_invert_compose(other);
  426. }
  427. LightReMutexHolder holder(*_states_lock);
  428. // Is this composition already cached?
  429. int index = _invert_composition_cache.find(other);
  430. if (index != -1) {
  431. Composition &comp = ((RenderState *)this)->_invert_composition_cache.modify_data(index);
  432. if (comp._result == (const RenderState *)NULL) {
  433. // Well, it wasn't cached already, but we already had an entry
  434. // (probably created for the reverse direction), so use the same
  435. // entry to store the new result.
  436. CPT(RenderState) result = do_invert_compose(other);
  437. comp._result = result;
  438. if (result != (const RenderState *)this) {
  439. // See the comments below about the need to up the reference
  440. // count only when the result is not the same as this.
  441. result->cache_ref();
  442. }
  443. }
  444. // Here's the cache!
  445. _cache_stats.inc_hits();
  446. return comp._result;
  447. }
  448. _cache_stats.inc_misses();
  449. // We need to make a new cache entry, both in this object and in the
  450. // other object. We make both records so the other RenderState
  451. // object will know to delete the entry from this object when it
  452. // destructs, and vice-versa.
  453. // The cache entry in this object is the only one that indicates the
  454. // result; the other will be NULL for now.
  455. CPT(RenderState) result = do_invert_compose(other);
  456. _cache_stats.add_total_size(1);
  457. _cache_stats.inc_adds(_invert_composition_cache.get_size() == 0);
  458. ((RenderState *)this)->_invert_composition_cache[other]._result = result;
  459. if (other != this) {
  460. _cache_stats.add_total_size(1);
  461. _cache_stats.inc_adds(other->_invert_composition_cache.get_size() == 0);
  462. ((RenderState *)other)->_invert_composition_cache[this]._result = NULL;
  463. }
  464. if (result != (const RenderState *)this) {
  465. // If the result of compose() is something other than this,
  466. // explicitly increment the reference count. We have to be sure
  467. // to decrement it again later, when the composition entry is
  468. // removed from the cache.
  469. result->cache_ref();
  470. // (If the result was just this again, we still store the
  471. // result, but we don't increment the reference count, since
  472. // that would be a self-referential leak.)
  473. }
  474. return result;
  475. }
  476. ////////////////////////////////////////////////////////////////////
  477. // Function: RenderState::add_attrib
  478. // Access: Published
  479. // Description: Returns a new RenderState object that represents the
  480. // same as the source state, with the new RenderAttrib
  481. // added. If there is already a RenderAttrib with the
  482. // same type, it is replaced (unless the override is
  483. // lower).
  484. ////////////////////////////////////////////////////////////////////
  485. CPT(RenderState) RenderState::
  486. add_attrib(const RenderAttrib *attrib, int override) const {
  487. int slot = attrib->get_slot();
  488. if (_filled_slots.get_bit(slot) &&
  489. _attributes[slot]._override > override) {
  490. // The existing attribute overrides.
  491. return this;
  492. }
  493. // The new attribute replaces.
  494. RenderState *new_state = new RenderState(*this);
  495. new_state->_attributes[slot].set(attrib, override);
  496. new_state->_filled_slots.set_bit(slot);
  497. return return_new(new_state);
  498. }
  499. ////////////////////////////////////////////////////////////////////
  500. // Function: RenderState::set_attrib
  501. // Access: Published
  502. // Description: Returns a new RenderState object that represents the
  503. // same as the source state, with the new RenderAttrib
  504. // added. If there is already a RenderAttrib with the
  505. // same type, it is replaced unconditionally. The
  506. // override is not changed.
  507. ////////////////////////////////////////////////////////////////////
  508. CPT(RenderState) RenderState::
  509. set_attrib(const RenderAttrib *attrib) const {
  510. RenderState *new_state = new RenderState(*this);
  511. int slot = attrib->get_slot();
  512. new_state->_attributes[slot]._attrib = attrib;
  513. new_state->_filled_slots.set_bit(slot);
  514. return return_new(new_state);
  515. }
  516. ////////////////////////////////////////////////////////////////////
  517. // Function: RenderState::set_attrib
  518. // Access: Published
  519. // Description: Returns a new RenderState object that represents the
  520. // same as the source state, with the new RenderAttrib
  521. // added. If there is already a RenderAttrib with the
  522. // same type, it is replaced unconditionally. The
  523. // override is also replaced unconditionally.
  524. ////////////////////////////////////////////////////////////////////
  525. CPT(RenderState) RenderState::
  526. set_attrib(const RenderAttrib *attrib, int override) const {
  527. RenderState *new_state = new RenderState(*this);
  528. int slot = attrib->get_slot();
  529. new_state->_attributes[slot].set(attrib, override);
  530. new_state->_filled_slots.set_bit(slot);
  531. return return_new(new_state);
  532. }
  533. ////////////////////////////////////////////////////////////////////
  534. // Function: RenderState::remove_attrib
  535. // Access: Published
  536. // Description: Returns a new RenderState object that represents the
  537. // same as the source state, with the indicated
  538. // RenderAttrib removed.
  539. ////////////////////////////////////////////////////////////////////
  540. CPT(RenderState) RenderState::
  541. remove_attrib(int slot) const {
  542. if (_attributes[slot]._attrib == NULL) {
  543. // Already removed.
  544. return this;
  545. }
  546. // Will this bring us down to the empty state?
  547. if (_filled_slots.get_num_on_bits() == 1) {
  548. return _empty_state;
  549. }
  550. RenderState *new_state = new RenderState(*this);
  551. new_state->_attributes[slot].set(NULL, 0);
  552. new_state->_filled_slots.clear_bit(slot);
  553. return return_new(new_state);
  554. }
  555. ////////////////////////////////////////////////////////////////////
  556. // Function: RenderState::adjust_all_priorities
  557. // Access: Published
  558. // Description: Returns a new RenderState object that represents the
  559. // same as the source state, with all attributes'
  560. // override values incremented (or decremented, if
  561. // negative) by the indicated amount. If the override
  562. // would drop below zero, it is set to zero.
  563. ////////////////////////////////////////////////////////////////////
  564. CPT(RenderState) RenderState::
  565. adjust_all_priorities(int adjustment) const {
  566. RenderState *new_state = new RenderState(*this);
  567. SlotMask mask = _filled_slots;
  568. int slot = mask.get_lowest_on_bit();
  569. while (slot >= 0) {
  570. Attribute &attrib = new_state->_attributes[slot];
  571. nassertr(attrib._attrib != (RenderAttrib *)NULL, this);
  572. attrib._override = max(attrib._override + adjustment, 0);
  573. mask.clear_bit(slot);
  574. slot = mask.get_lowest_on_bit();
  575. }
  576. return return_new(new_state);
  577. }
  578. ////////////////////////////////////////////////////////////////////
  579. // Function: RenderState::unref
  580. // Access: Published, Virtual
  581. // Description: This method overrides ReferenceCount::unref() to
  582. // check whether the remaining reference count is
  583. // entirely in the cache, and if so, it checks for and
  584. // breaks a cycle in the cache involving this object.
  585. // This is designed to prevent leaks from cyclical
  586. // references within the cache.
  587. ////////////////////////////////////////////////////////////////////
  588. bool RenderState::
  589. unref() const {
  590. if (!state_cache || garbage_collect_states) {
  591. // If we're not using the cache at all, or if we're relying on
  592. // garbage collection, just allow the pointer to unref normally.
  593. return ReferenceCount::unref();
  594. }
  595. // Here is the normal refcounting case, with a normal cache, and
  596. // without garbage collection in effect. In this case we will pull
  597. // the object out of the cache when its reference count goes to 0.
  598. // We always have to grab the lock, since we will definitely need to
  599. // be holding it if we happen to drop the reference count to 0.
  600. // Having to grab the lock at every call to unref() is a big
  601. // limiting factor on parallelization.
  602. LightReMutexHolder holder(*_states_lock);
  603. if (auto_break_cycles && uniquify_states) {
  604. if (get_cache_ref_count() > 0 &&
  605. get_ref_count() == get_cache_ref_count() + 1) {
  606. // If we are about to remove the one reference that is not in the
  607. // cache, leaving only references in the cache, then we need to
  608. // check for a cycle involving this RenderState and break it if
  609. // it exists.
  610. ((RenderState *)this)->detect_and_break_cycles();
  611. }
  612. }
  613. if (ReferenceCount::unref()) {
  614. // The reference count is still nonzero.
  615. return true;
  616. }
  617. // The reference count has just reached zero. Make sure the object
  618. // is removed from the global object pool, before anyone else finds
  619. // it and tries to ref it.
  620. ((RenderState *)this)->release_new();
  621. ((RenderState *)this)->remove_cache_pointers();
  622. return false;
  623. }
  624. ////////////////////////////////////////////////////////////////////
  625. // Function: RenderState::get_auto_shader_state
  626. // Access: Published
  627. // Description: Returns the base RenderState that should have the
  628. // generated_shader stored within it, for generated
  629. // shader states. The returned object might be the same
  630. // as this object, or it might be a different
  631. // RenderState with certain attributes removed, or set
  632. // to their default values.
  633. //
  634. // The point is to avoid needless regeneration of the
  635. // shader attrib by storing the generated shader on a
  636. // common RenderState object, with all irrelevant
  637. // attributes removed.
  638. ////////////////////////////////////////////////////////////////////
  639. const RenderState *RenderState::
  640. get_auto_shader_state() const {
  641. if (_auto_shader_state == (const RenderState *)NULL) {
  642. ((RenderState *)this)->assign_auto_shader_state();
  643. }
  644. return _auto_shader_state;
  645. }
  646. ////////////////////////////////////////////////////////////////////
  647. // Function: RenderState::output
  648. // Access: Published
  649. // Description:
  650. ////////////////////////////////////////////////////////////////////
  651. void RenderState::
  652. output(ostream &out) const {
  653. out << "S:";
  654. if (is_empty()) {
  655. out << "(empty)";
  656. } else {
  657. out << "(";
  658. const char *sep = "";
  659. SlotMask mask = _filled_slots;
  660. int slot = mask.get_lowest_on_bit();
  661. while (slot >= 0) {
  662. const Attribute &attrib = _attributes[slot];
  663. nassertv(attrib._attrib != (RenderAttrib *)NULL);
  664. out << sep << attrib._attrib->get_type();
  665. sep = " ";
  666. mask.clear_bit(slot);
  667. slot = mask.get_lowest_on_bit();
  668. }
  669. out << ")";
  670. }
  671. }
  672. ////////////////////////////////////////////////////////////////////
  673. // Function: RenderState::write
  674. // Access: Published
  675. // Description:
  676. ////////////////////////////////////////////////////////////////////
  677. void RenderState::
  678. write(ostream &out, int indent_level) const {
  679. if (is_empty()) {
  680. indent(out, indent_level)
  681. << "(empty)\n";
  682. }
  683. SlotMask mask = _filled_slots;
  684. int slot = mask.get_lowest_on_bit();
  685. while (slot >= 0) {
  686. const Attribute &attrib = _attributes[slot];
  687. nassertv(attrib._attrib != (RenderAttrib *)NULL);
  688. attrib._attrib->write(out, indent_level);
  689. mask.clear_bit(slot);
  690. slot = mask.get_lowest_on_bit();
  691. }
  692. }
  693. ////////////////////////////////////////////////////////////////////
  694. // Function: RenderState::get_max_priority
  695. // Access: Published, Static
  696. // Description: Returns the maximum priority number (sometimes called
  697. // override) that may be set on any node. This may or
  698. // may not be enforced, but the scene graph code assumes
  699. // that no priority numbers will be larger than this,
  700. // and some effects may not work properly if you use a
  701. // larger number.
  702. ////////////////////////////////////////////////////////////////////
  703. int RenderState::
  704. get_max_priority() {
  705. return 1000000000;
  706. }
  707. ////////////////////////////////////////////////////////////////////
  708. // Function: RenderState::get_num_states
  709. // Access: Published, Static
  710. // Description: Returns the total number of unique RenderState
  711. // objects allocated in the world. This will go up and
  712. // down during normal operations.
  713. ////////////////////////////////////////////////////////////////////
  714. int RenderState::
  715. get_num_states() {
  716. if (_states == (States *)NULL) {
  717. return 0;
  718. }
  719. LightReMutexHolder holder(*_states_lock);
  720. return _states->get_num_entries();
  721. }
  722. ////////////////////////////////////////////////////////////////////
  723. // Function: RenderState::get_num_unused_states
  724. // Access: Published, Static
  725. // Description: Returns the total number of RenderState objects that
  726. // have been allocated but have no references outside of
  727. // the internal RenderState cache.
  728. //
  729. // A nonzero return value is not necessarily indicative
  730. // of leaked references; it is normal for two
  731. // RenderState objects, both of which have references
  732. // held outside the cache, to have to result of their
  733. // composition stored within the cache. This result
  734. // will be retained within the cache until one of the
  735. // base RenderStates is released.
  736. //
  737. // Use list_cycles() to get an idea of the number of
  738. // actual "leaked" RenderState objects.
  739. ////////////////////////////////////////////////////////////////////
  740. int RenderState::
  741. get_num_unused_states() {
  742. if (_states == (States *)NULL) {
  743. return 0;
  744. }
  745. LightReMutexHolder holder(*_states_lock);
  746. // First, we need to count the number of times each RenderState
  747. // object is recorded in the cache.
  748. typedef pmap<const RenderState *, int> StateCount;
  749. StateCount state_count;
  750. int size = _states->get_size();
  751. for (int si = 0; si < size; ++si) {
  752. if (!_states->has_element(si)) {
  753. continue;
  754. }
  755. const RenderState *state = _states->get_key(si);
  756. int i;
  757. int cache_size = state->_composition_cache.get_size();
  758. for (i = 0; i < cache_size; ++i) {
  759. if (state->_composition_cache.has_element(i)) {
  760. const RenderState *result = state->_composition_cache.get_data(i)._result;
  761. if (result != (const RenderState *)NULL && result != state) {
  762. // Here's a RenderState that's recorded in the cache.
  763. // Count it.
  764. pair<StateCount::iterator, bool> ir =
  765. state_count.insert(StateCount::value_type(result, 1));
  766. if (!ir.second) {
  767. // If the above insert operation fails, then it's already in
  768. // the cache; increment its value.
  769. (*(ir.first)).second++;
  770. }
  771. }
  772. }
  773. }
  774. cache_size = state->_invert_composition_cache.get_size();
  775. for (i = 0; i < cache_size; ++i) {
  776. if (state->_invert_composition_cache.has_element(i)) {
  777. const RenderState *result = state->_invert_composition_cache.get_data(i)._result;
  778. if (result != (const RenderState *)NULL && result != state) {
  779. pair<StateCount::iterator, bool> ir =
  780. state_count.insert(StateCount::value_type(result, 1));
  781. if (!ir.second) {
  782. (*(ir.first)).second++;
  783. }
  784. }
  785. }
  786. }
  787. }
  788. // Now that we have the appearance count of each RenderState
  789. // object, we can tell which ones are unreferenced outside of the
  790. // RenderState cache, by comparing these to the reference counts.
  791. int num_unused = 0;
  792. StateCount::iterator sci;
  793. for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
  794. const RenderState *state = (*sci).first;
  795. int count = (*sci).second;
  796. nassertr(count == state->get_cache_ref_count(), num_unused);
  797. nassertr(count <= state->get_ref_count(), num_unused);
  798. if (count == state->get_ref_count()) {
  799. num_unused++;
  800. if (pgraph_cat.is_debug()) {
  801. pgraph_cat.debug()
  802. << "Unused state: " << (void *)state << ":"
  803. << state->get_ref_count() << " =\n";
  804. state->write(pgraph_cat.debug(false), 2);
  805. }
  806. }
  807. }
  808. return num_unused;
  809. }
  810. ////////////////////////////////////////////////////////////////////
  811. // Function: RenderState::clear_cache
  812. // Access: Published, Static
  813. // Description: Empties the cache of composed RenderStates. This
  814. // makes every RenderState forget what results when
  815. // it is composed with other RenderStates.
  816. //
  817. // This will eliminate any RenderState objects that
  818. // have been allocated but have no references outside of
  819. // the internal RenderState map. It will not
  820. // eliminate RenderState objects that are still in
  821. // use.
  822. //
  823. // Nowadays, this method should not be necessary, as
  824. // reference-count cycles in the composition cache
  825. // should be automatically detected and broken.
  826. //
  827. // The return value is the number of RenderStates
  828. // freed by this operation.
  829. ////////////////////////////////////////////////////////////////////
  830. int RenderState::
  831. clear_cache() {
  832. if (_states == (States *)NULL) {
  833. return 0;
  834. }
  835. LightReMutexHolder holder(*_states_lock);
  836. PStatTimer timer(_cache_update_pcollector);
  837. int orig_size = _states->get_num_entries();
  838. // First, we need to copy the entire set of states to a temporary
  839. // vector, reference-counting each object. That way we can walk
  840. // through the copy, without fear of dereferencing (and deleting)
  841. // the objects in the map as we go.
  842. {
  843. typedef pvector< CPT(RenderState) > TempStates;
  844. TempStates temp_states;
  845. temp_states.reserve(orig_size);
  846. int size = _states->get_size();
  847. for (int si = 0; si < size; ++si) {
  848. if (!_states->has_element(si)) {
  849. continue;
  850. }
  851. const RenderState *state = _states->get_key(si);
  852. temp_states.push_back(state);
  853. }
  854. // Now it's safe to walk through the list, destroying the cache
  855. // within each object as we go. Nothing will be destructed till
  856. // we're done.
  857. TempStates::iterator ti;
  858. for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
  859. RenderState *state = (RenderState *)(*ti).p();
  860. int i;
  861. int cache_size = state->_composition_cache.get_size();
  862. for (i = 0; i < cache_size; ++i) {
  863. if (state->_composition_cache.has_element(i)) {
  864. const RenderState *result = state->_composition_cache.get_data(i)._result;
  865. if (result != (const RenderState *)NULL && result != state) {
  866. result->cache_unref();
  867. nassertr(result->get_ref_count() > 0, 0);
  868. }
  869. }
  870. }
  871. _cache_stats.add_total_size(-state->_composition_cache.get_num_entries());
  872. state->_composition_cache.clear();
  873. cache_size = state->_invert_composition_cache.get_size();
  874. for (i = 0; i < cache_size; ++i) {
  875. if (state->_invert_composition_cache.has_element(i)) {
  876. const RenderState *result = state->_invert_composition_cache.get_data(i)._result;
  877. if (result != (const RenderState *)NULL && result != state) {
  878. result->cache_unref();
  879. nassertr(result->get_ref_count() > 0, 0);
  880. }
  881. }
  882. }
  883. _cache_stats.add_total_size(-state->_invert_composition_cache.get_num_entries());
  884. state->_invert_composition_cache.clear();
  885. }
  886. // Once this block closes and the temp_states object goes away,
  887. // all the destruction will begin. Anything whose reference was
  888. // held only within the various objects' caches will go away.
  889. }
  890. int new_size = _states->get_num_entries();
  891. return orig_size - new_size;
  892. }
  893. ////////////////////////////////////////////////////////////////////
  894. // Function: RenderState::garbage_collect
  895. // Access: Published, Static
  896. // Description: Performs a garbage-collection cycle. This must be
  897. // called periodically if garbage-collect-states is true
  898. // to ensure that RenderStates get cleaned up
  899. // appropriately. It does no harm to call it even if
  900. // this variable is not true, but there is probably no
  901. // advantage in that case.
  902. //
  903. // This automatically calls
  904. // RenderAttrib::garbage_collect() as well.
  905. ////////////////////////////////////////////////////////////////////
  906. int RenderState::
  907. garbage_collect() {
  908. int num_attribs = RenderAttrib::garbage_collect();
  909. if (_states == (States *)NULL || !garbage_collect_states) {
  910. return num_attribs;
  911. }
  912. LightReMutexHolder holder(*_states_lock);
  913. PStatTimer timer(_garbage_collect_pcollector);
  914. int orig_size = _states->get_num_entries();
  915. // How many elements to process this pass?
  916. int size = _states->get_size();
  917. int num_this_pass = int(size * garbage_collect_states_rate);
  918. if (num_this_pass <= 0) {
  919. return num_attribs;
  920. }
  921. num_this_pass = min(num_this_pass, size);
  922. int stop_at_element = (_garbage_index + num_this_pass) % size;
  923. int num_elements = 0;
  924. int si = _garbage_index;
  925. do {
  926. if (_states->has_element(si)) {
  927. ++num_elements;
  928. RenderState *state = (RenderState *)_states->get_key(si);
  929. if (auto_break_cycles && uniquify_states) {
  930. if (state->get_cache_ref_count() > 0 &&
  931. state->get_ref_count() == state->get_cache_ref_count()) {
  932. // If we have removed all the references to this state not in
  933. // the cache, leaving only references in the cache, then we
  934. // need to check for a cycle involving this RenderState and
  935. // break it if it exists.
  936. state->detect_and_break_cycles();
  937. }
  938. }
  939. if (state->get_ref_count() == 1) {
  940. // This state has recently been unreffed to 1 (the one we
  941. // added when we stored it in the cache). Now it's time to
  942. // delete it. This is safe, because we're holding the
  943. // _states_lock, so it's not possible for some other thread to
  944. // find the state in the cache and ref it while we're doing
  945. // this.
  946. state->release_new();
  947. state->remove_cache_pointers();
  948. state->cache_unref();
  949. delete state;
  950. }
  951. }
  952. si = (si + 1) % size;
  953. } while (si != stop_at_element);
  954. _garbage_index = si;
  955. nassertr(_states->validate(), 0);
  956. int new_size = _states->get_num_entries();
  957. return orig_size - new_size + num_attribs;
  958. }
  959. ////////////////////////////////////////////////////////////////////
  960. // Function: RenderState::clear_munger_cache
  961. // Access: Published, Static
  962. // Description: Completely empties the cache of state + gsg ->
  963. // munger, for all states and all gsg's. Normally there
  964. // is no need to empty this cache.
  965. ////////////////////////////////////////////////////////////////////
  966. void RenderState::
  967. clear_munger_cache() {
  968. LightReMutexHolder holder(*_states_lock);
  969. int size = _states->get_size();
  970. for (int si = 0; si < size; ++si) {
  971. if (!_states->has_element(si)) {
  972. continue;
  973. }
  974. RenderState *state = (RenderState *)(_states->get_key(si));
  975. state->_mungers.clear();
  976. state->_last_mi = -1;
  977. }
  978. }
  979. ////////////////////////////////////////////////////////////////////
  980. // Function: RenderState::list_cycles
  981. // Access: Published, Static
  982. // Description: Detects all of the reference-count cycles in the
  983. // cache and reports them to standard output.
  984. //
  985. // These cycles may be inadvertently created when state
  986. // compositions cycle back to a starting point.
  987. // Nowadays, these cycles should be automatically
  988. // detected and broken, so this method should never list
  989. // any cycles unless there is a bug in that detection
  990. // logic.
  991. //
  992. // The cycles listed here are not leaks in the strictest
  993. // sense of the word, since they can be reclaimed by a
  994. // call to clear_cache(); but they will not be reclaimed
  995. // automatically.
  996. ////////////////////////////////////////////////////////////////////
  997. void RenderState::
  998. list_cycles(ostream &out) {
  999. if (_states == (States *)NULL) {
  1000. return;
  1001. }
  1002. LightReMutexHolder holder(*_states_lock);
  1003. typedef pset<const RenderState *> VisitedStates;
  1004. VisitedStates visited;
  1005. CompositionCycleDesc cycle_desc;
  1006. int size = _states->get_size();
  1007. for (int si = 0; si < size; ++si) {
  1008. if (!_states->has_element(si)) {
  1009. continue;
  1010. }
  1011. const RenderState *state = _states->get_key(si);
  1012. bool inserted = visited.insert(state).second;
  1013. if (inserted) {
  1014. ++_last_cycle_detect;
  1015. if (r_detect_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) {
  1016. // This state begins a cycle.
  1017. CompositionCycleDesc::reverse_iterator csi;
  1018. out << "\nCycle detected of length " << cycle_desc.size() + 1 << ":\n"
  1019. << "state " << (void *)state << ":" << state->get_ref_count()
  1020. << " =\n";
  1021. state->write(out, 2);
  1022. for (csi = cycle_desc.rbegin(); csi != cycle_desc.rend(); ++csi) {
  1023. const CompositionCycleDescEntry &entry = (*csi);
  1024. if (entry._inverted) {
  1025. out << "invert composed with ";
  1026. } else {
  1027. out << "composed with ";
  1028. }
  1029. out << (const void *)entry._obj << ":" << entry._obj->get_ref_count()
  1030. << " " << *entry._obj << "\n"
  1031. << "produces " << (const void *)entry._result << ":"
  1032. << entry._result->get_ref_count() << " =\n";
  1033. entry._result->write(out, 2);
  1034. visited.insert(entry._result);
  1035. }
  1036. cycle_desc.clear();
  1037. } else {
  1038. ++_last_cycle_detect;
  1039. if (r_detect_reverse_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) {
  1040. // This state begins a cycle.
  1041. CompositionCycleDesc::iterator csi;
  1042. out << "\nReverse cycle detected of length " << cycle_desc.size() + 1 << ":\n"
  1043. << "state ";
  1044. for (csi = cycle_desc.begin(); csi != cycle_desc.end(); ++csi) {
  1045. const CompositionCycleDescEntry &entry = (*csi);
  1046. out << (const void *)entry._result << ":"
  1047. << entry._result->get_ref_count() << " =\n";
  1048. entry._result->write(out, 2);
  1049. out << (const void *)entry._obj << ":"
  1050. << entry._obj->get_ref_count() << " =\n";
  1051. entry._obj->write(out, 2);
  1052. visited.insert(entry._result);
  1053. }
  1054. out << (void *)state << ":"
  1055. << state->get_ref_count() << " =\n";
  1056. state->write(out, 2);
  1057. cycle_desc.clear();
  1058. }
  1059. }
  1060. }
  1061. }
  1062. }
  1063. ////////////////////////////////////////////////////////////////////
  1064. // Function: RenderState::list_states
  1065. // Access: Published, Static
  1066. // Description: Lists all of the RenderStates in the cache to the
  1067. // output stream, one per line. This can be quite a lot
  1068. // of output if the cache is large, so be prepared.
  1069. ////////////////////////////////////////////////////////////////////
  1070. void RenderState::
  1071. list_states(ostream &out) {
  1072. if (_states == (States *)NULL) {
  1073. out << "0 states:\n";
  1074. return;
  1075. }
  1076. LightReMutexHolder holder(*_states_lock);
  1077. out << _states->get_num_entries() << " states:\n";
  1078. int size = _states->get_size();
  1079. for (int si = 0; si < size; ++si) {
  1080. if (!_states->has_element(si)) {
  1081. continue;
  1082. }
  1083. const RenderState *state = _states->get_key(si);
  1084. state->write(out, 2);
  1085. }
  1086. }
  1087. ////////////////////////////////////////////////////////////////////
  1088. // Function: RenderState::validate_states
  1089. // Access: Published, Static
  1090. // Description: Ensures that the cache is still stored in sorted
  1091. // order, and that none of the cache elements have been
  1092. // inadvertently deleted. Returns true if so, false if
  1093. // there is a problem (which implies someone has
  1094. // modified one of the supposedly-const RenderState
  1095. // objects).
  1096. ////////////////////////////////////////////////////////////////////
  1097. bool RenderState::
  1098. validate_states() {
  1099. if (_states == (States *)NULL) {
  1100. return true;
  1101. }
  1102. PStatTimer timer(_state_validate_pcollector);
  1103. LightReMutexHolder holder(*_states_lock);
  1104. if (_states->is_empty()) {
  1105. return true;
  1106. }
  1107. if (!_states->validate()) {
  1108. pgraph_cat.error()
  1109. << "RenderState::_states cache is invalid!\n";
  1110. return false;
  1111. }
  1112. int size = _states->get_size();
  1113. int si = 0;
  1114. while (si < size && !_states->has_element(si)) {
  1115. ++si;
  1116. }
  1117. nassertr(si < size, false);
  1118. nassertr(_states->get_key(si)->get_ref_count() >= 0, false);
  1119. int snext = si;
  1120. ++snext;
  1121. while (snext < size && !_states->has_element(snext)) {
  1122. ++snext;
  1123. }
  1124. while (snext < size) {
  1125. nassertr(_states->get_key(snext)->get_ref_count() >= 0, false);
  1126. const RenderState *ssi = _states->get_key(si);
  1127. const RenderState *ssnext = _states->get_key(snext);
  1128. int c = ssi->compare_to(*ssnext);
  1129. int ci = ssnext->compare_to(*ssi);
  1130. if ((ci < 0) != (c > 0) ||
  1131. (ci > 0) != (c < 0) ||
  1132. (ci == 0) != (c == 0)) {
  1133. pgraph_cat.error()
  1134. << "RenderState::compare_to() not defined properly!\n";
  1135. pgraph_cat.error(false)
  1136. << "(a, b): " << c << "\n";
  1137. pgraph_cat.error(false)
  1138. << "(b, a): " << ci << "\n";
  1139. ssi->write(pgraph_cat.error(false), 2);
  1140. ssnext->write(pgraph_cat.error(false), 2);
  1141. return false;
  1142. }
  1143. si = snext;
  1144. ++snext;
  1145. while (snext < size && !_states->has_element(snext)) {
  1146. ++snext;
  1147. }
  1148. }
  1149. return true;
  1150. }
  1151. ////////////////////////////////////////////////////////////////////
  1152. // Function: RenderState::get_geom_rendering
  1153. // Access: Published
  1154. // Description: Returns the union of the Geom::GeomRendering bits
  1155. // that will be required once this RenderState is
  1156. // applied to a geom which includes the indicated
  1157. // geom_rendering bits.
  1158. ////////////////////////////////////////////////////////////////////
  1159. int RenderState::
  1160. get_geom_rendering(int geom_rendering) const {
  1161. const RenderModeAttrib *render_mode;
  1162. const TexGenAttrib *tex_gen;
  1163. const TexMatrixAttrib *tex_matrix;
  1164. if (get_attrib(render_mode)) {
  1165. geom_rendering = render_mode->get_geom_rendering(geom_rendering);
  1166. }
  1167. if (get_attrib(tex_gen)) {
  1168. geom_rendering = tex_gen->get_geom_rendering(geom_rendering);
  1169. }
  1170. if (get_attrib(tex_matrix)) {
  1171. geom_rendering = tex_matrix->get_geom_rendering(geom_rendering);
  1172. }
  1173. return geom_rendering;
  1174. }
  1175. ////////////////////////////////////////////////////////////////////
  1176. // Function: RenderState::bin_removed
  1177. // Access: Public, Static
  1178. // Description: Intended to be called by
  1179. // CullBinManager::remove_bin(), this informs all the
  1180. // RenderStates in the world to remove the indicated
  1181. // bin_index from their cache if it has been cached.
  1182. ////////////////////////////////////////////////////////////////////
  1183. void RenderState::
  1184. bin_removed(int bin_index) {
  1185. // Do something here.
  1186. nassertv(false);
  1187. }
  1188. ////////////////////////////////////////////////////////////////////
  1189. // Function: RenderState::validate_filled_slots
  1190. // Access: Private
  1191. // Description: Returns true if the _filled_slots bitmask is
  1192. // consistent with the table of RenderAttrib pointers,
  1193. // false otherwise.
  1194. ////////////////////////////////////////////////////////////////////
  1195. bool RenderState::
  1196. validate_filled_slots() const {
  1197. SlotMask mask;
  1198. RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
  1199. int max_slots = reg->get_max_slots();
  1200. for (int slot = 1; slot < max_slots; ++slot) {
  1201. const Attribute &attribute = _attributes[slot];
  1202. if (attribute._attrib != (RenderAttrib *)NULL) {
  1203. mask.set_bit(slot);
  1204. }
  1205. }
  1206. return (mask == _filled_slots);
  1207. }
  1208. ////////////////////////////////////////////////////////////////////
  1209. // Function: RenderState::do_calc_hash
  1210. // Access: Private
  1211. // Description: Computes a suitable hash value for phash_map.
  1212. ////////////////////////////////////////////////////////////////////
  1213. void RenderState::
  1214. do_calc_hash() {
  1215. _hash = 0;
  1216. SlotMask mask = _filled_slots;
  1217. int slot = mask.get_lowest_on_bit();
  1218. while (slot >= 0) {
  1219. const Attribute &attrib = _attributes[slot];
  1220. nassertv(attrib._attrib != (RenderAttrib *)NULL);
  1221. _hash = pointer_hash::add_hash(_hash, attrib._attrib);
  1222. _hash = int_hash::add_hash(_hash, attrib._override);
  1223. mask.clear_bit(slot);
  1224. slot = mask.get_lowest_on_bit();
  1225. }
  1226. _flags |= F_hash_known;
  1227. }
  1228. ////////////////////////////////////////////////////////////////////
  1229. // Function: RenderState::assign_auto_shader_state
  1230. // Access: Private
  1231. // Description: Sets _auto_shader_state to the appropriate
  1232. // RenderState object pointer, either the same pointer
  1233. // as this object, or some other (simpler) RenderState.
  1234. ////////////////////////////////////////////////////////////////////
  1235. void RenderState::
  1236. assign_auto_shader_state() {
  1237. CPT(RenderState) state = do_calc_auto_shader_state();
  1238. {
  1239. LightReMutexHolder holder(*_states_lock);
  1240. if (_auto_shader_state == (const RenderState *)NULL) {
  1241. _auto_shader_state = state;
  1242. if (_auto_shader_state != this) {
  1243. _auto_shader_state->cache_ref();
  1244. }
  1245. }
  1246. }
  1247. }
  1248. ////////////////////////////////////////////////////////////////////
  1249. // Function: RenderState::do_calc_auto_shader_state
  1250. // Access: Private
  1251. // Description: Returns the appropriate RenderState that should be
  1252. // used to store the auto shader pointer for nodes that
  1253. // shader this RenderState.
  1254. ////////////////////////////////////////////////////////////////////
  1255. CPT(RenderState) RenderState::
  1256. do_calc_auto_shader_state() {
  1257. RenderState *state = new RenderState;
  1258. SlotMask mask = _filled_slots;
  1259. int slot = mask.get_lowest_on_bit();
  1260. while (slot >= 0) {
  1261. const Attribute &attrib = _attributes[slot];
  1262. nassertr(attrib._attrib != (RenderAttrib *)NULL, this);
  1263. CPT(RenderAttrib) new_attrib = attrib._attrib->get_auto_shader_attrib(this);
  1264. if (new_attrib != NULL) {
  1265. nassertr(new_attrib->get_slot() == slot, this);
  1266. state->_attributes[slot].set(new_attrib, 0);
  1267. state->_filled_slots.set_bit(slot);
  1268. }
  1269. mask.clear_bit(slot);
  1270. slot = mask.get_lowest_on_bit();
  1271. }
  1272. return return_new(state);
  1273. }
  1274. ////////////////////////////////////////////////////////////////////
  1275. // Function: RenderState::return_new
  1276. // Access: Private, Static
  1277. // Description: This function is used to share a common RenderState
  1278. // pointer for all equivalent RenderState objects.
  1279. //
  1280. // This is different from return_unique() in that it
  1281. // does not actually guarantee a unique pointer, unless
  1282. // uniquify-states is set.
  1283. ////////////////////////////////////////////////////////////////////
  1284. CPT(RenderState) RenderState::
  1285. return_new(RenderState *state) {
  1286. nassertr(state != (RenderState *)NULL, state);
  1287. // Make sure we don't have anything in the 0 slot. If we did, that
  1288. // would indicate an uninitialized slot number.
  1289. #ifndef NDEBUG
  1290. if (state->_attributes[0]._attrib != (RenderAttrib *)NULL) {
  1291. const RenderAttrib *attrib = state->_attributes[0]._attrib;
  1292. if (attrib->get_type() == TypeHandle::none()) {
  1293. ((RenderAttrib *)attrib)->force_init_type();
  1294. pgraph_cat->error()
  1295. << "Uninitialized RenderAttrib type: " << attrib->get_type()
  1296. << "\n";
  1297. } else {
  1298. static pset<TypeHandle> already_reported;
  1299. if (already_reported.insert(attrib->get_type()).second) {
  1300. pgraph_cat->error()
  1301. << attrib->get_type() << " did not initialize its slot number.\n";
  1302. }
  1303. }
  1304. }
  1305. #endif
  1306. state->_attributes[0]._attrib = NULL;
  1307. state->_filled_slots.clear_bit(0);
  1308. #ifndef NDEBUG
  1309. nassertr(state->validate_filled_slots(), state);
  1310. #endif
  1311. if (!uniquify_states && !state->is_empty()) {
  1312. return state;
  1313. }
  1314. return return_unique(state);
  1315. }
  1316. ////////////////////////////////////////////////////////////////////
  1317. // Function: RenderState::return_unique
  1318. // Access: Private, Static
  1319. // Description: This function is used to share a common RenderState
  1320. // pointer for all equivalent RenderState objects.
  1321. //
  1322. // See the similar logic in RenderAttrib. The idea is
  1323. // to create a new RenderState object and pass it
  1324. // through this function, which will share the pointer
  1325. // with a previously-created RenderState object if it is
  1326. // equivalent.
  1327. ////////////////////////////////////////////////////////////////////
  1328. CPT(RenderState) RenderState::
  1329. return_unique(RenderState *state) {
  1330. nassertr(state != (RenderState *)NULL, NULL);
  1331. if (!state_cache) {
  1332. return state;
  1333. }
  1334. #ifndef NDEBUG
  1335. if (paranoid_const) {
  1336. nassertr(validate_states(), state);
  1337. }
  1338. #endif
  1339. LightReMutexHolder holder(*_states_lock);
  1340. if (state->_saved_entry != -1) {
  1341. // This state is already in the cache.
  1342. //nassertr(_states->find(state) == state->_saved_entry, pt_state);
  1343. return state;
  1344. }
  1345. // Ensure each of the individual attrib pointers has been uniquified
  1346. // before we add the state to the cache.
  1347. if (!uniquify_attribs && !state->is_empty()) {
  1348. SlotMask mask = state->_filled_slots;
  1349. int slot = mask.get_lowest_on_bit();
  1350. while (slot >= 0) {
  1351. Attribute &attrib = state->_attributes[slot];
  1352. nassertd(attrib._attrib != (RenderAttrib *)NULL) continue;
  1353. attrib._attrib = attrib._attrib->get_unique();
  1354. mask.clear_bit(slot);
  1355. slot = mask.get_lowest_on_bit();
  1356. }
  1357. }
  1358. int si = _states->find(state);
  1359. if (si != -1) {
  1360. // There's an equivalent state already in the set. Return it.
  1361. // The state that was passed may be newly created and therefore
  1362. // may not be automatically deleted. Do that if necessary.
  1363. if (state->get_ref_count() == 0) {
  1364. delete state;
  1365. }
  1366. return _states->get_key(si);
  1367. }
  1368. // Not already in the set; add it.
  1369. if (garbage_collect_states) {
  1370. // If we'll be garbage collecting states explicitly, we'll
  1371. // increment the reference count when we store it in the cache, so
  1372. // that it won't be deleted while it's in it.
  1373. state->cache_ref();
  1374. }
  1375. si = _states->store(state, Empty());
  1376. // Save the index and return the input state.
  1377. state->_saved_entry = si;
  1378. return state;
  1379. }
  1380. ////////////////////////////////////////////////////////////////////
  1381. // Function: RenderState::do_compose
  1382. // Access: Private
  1383. // Description: The private implemention of compose(); this actually
  1384. // composes two RenderStates, without bothering with the
  1385. // cache.
  1386. ////////////////////////////////////////////////////////////////////
  1387. CPT(RenderState) RenderState::
  1388. do_compose(const RenderState *other) const {
  1389. PStatTimer timer(_state_compose_pcollector);
  1390. RenderState *new_state = new RenderState;
  1391. SlotMask mask = _filled_slots | other->_filled_slots;
  1392. new_state->_filled_slots = mask;
  1393. int slot = mask.get_lowest_on_bit();
  1394. while (slot >= 0) {
  1395. const Attribute &a = _attributes[slot];
  1396. const Attribute &b = other->_attributes[slot];
  1397. Attribute &result = new_state->_attributes[slot];
  1398. if (a._attrib == NULL) {
  1399. nassertr(b._attrib != NULL, this);
  1400. // B wins.
  1401. result = b;
  1402. } else if (b._attrib == NULL) {
  1403. // A wins.
  1404. result = a;
  1405. } else if (b._override < a._override) {
  1406. // A, the higher RenderAttrib, overrides.
  1407. result = a;
  1408. } else if (a._override < b._override &&
  1409. a._attrib->lower_attrib_can_override()) {
  1410. // B, the higher RenderAttrib, overrides. This is a special
  1411. // case; normally, a lower RenderAttrib does not override a
  1412. // higher one, even if it has a higher override value. But
  1413. // certain kinds of RenderAttribs redefine
  1414. // lower_attrib_can_override() to return true, allowing this
  1415. // override.
  1416. result = b;
  1417. } else {
  1418. // Either they have the same override value, or B is higher.
  1419. // In either case, the result is the composition of the two,
  1420. // with B's override value.
  1421. result.set(a._attrib->compose(b._attrib), b._override);
  1422. }
  1423. mask.clear_bit(slot);
  1424. slot = mask.get_lowest_on_bit();
  1425. }
  1426. return return_new(new_state);
  1427. }
  1428. ////////////////////////////////////////////////////////////////////
  1429. // Function: RenderState::do_invert_compose
  1430. // Access: Private
  1431. // Description: The private implemention of invert_compose().
  1432. ////////////////////////////////////////////////////////////////////
  1433. CPT(RenderState) RenderState::
  1434. do_invert_compose(const RenderState *other) const {
  1435. PStatTimer timer(_state_invert_pcollector);
  1436. RenderState *new_state = new RenderState;
  1437. SlotMask mask = _filled_slots | other->_filled_slots;
  1438. new_state->_filled_slots = mask;
  1439. int slot = mask.get_lowest_on_bit();
  1440. while (slot >= 0) {
  1441. const Attribute &a = _attributes[slot];
  1442. const Attribute &b = other->_attributes[slot];
  1443. Attribute &result = new_state->_attributes[slot];
  1444. if (a._attrib == NULL) {
  1445. nassertr(b._attrib != NULL, this);
  1446. // B wins.
  1447. result = b;
  1448. } else if (b._attrib == NULL) {
  1449. // A wins. Invert it.
  1450. RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
  1451. result.set(a._attrib->invert_compose(reg->get_slot_default(slot)), 0);
  1452. } else {
  1453. // Both are good. (Overrides are not used in invert_compose.)
  1454. // Compose.
  1455. result.set(a._attrib->invert_compose(b._attrib), 0);
  1456. }
  1457. mask.clear_bit(slot);
  1458. slot = mask.get_lowest_on_bit();
  1459. }
  1460. return return_new(new_state);
  1461. }
  1462. ////////////////////////////////////////////////////////////////////
  1463. // Function: RenderState::detect_and_break_cycles
  1464. // Access: Private
  1465. // Description: Detects whether there is a cycle in the cache that
  1466. // begins with this state. If any are detected, breaks
  1467. // them by removing this state from the cache.
  1468. ////////////////////////////////////////////////////////////////////
  1469. void RenderState::
  1470. detect_and_break_cycles() {
  1471. PStatTimer timer(_state_break_cycles_pcollector);
  1472. ++_last_cycle_detect;
  1473. if (r_detect_cycles(this, this, 1, _last_cycle_detect, NULL)) {
  1474. // Ok, we have a cycle. This will be a leak unless we break the
  1475. // cycle by freeing the cache on this object.
  1476. if (pgraph_cat.is_debug()) {
  1477. pgraph_cat.debug()
  1478. << "Breaking cycle involving " << (*this) << "\n";
  1479. }
  1480. ((RenderState *)this)->remove_cache_pointers();
  1481. } else {
  1482. ++_last_cycle_detect;
  1483. if (r_detect_reverse_cycles(this, this, 1, _last_cycle_detect, NULL)) {
  1484. if (pgraph_cat.is_debug()) {
  1485. pgraph_cat.debug()
  1486. << "Breaking cycle involving " << (*this) << "\n";
  1487. }
  1488. ((RenderState *)this)->remove_cache_pointers();
  1489. }
  1490. }
  1491. }
  1492. ////////////////////////////////////////////////////////////////////
  1493. // Function: RenderState::r_detect_cycles
  1494. // Access: Private, Static
  1495. // Description: Detects whether there is a cycle in the cache that
  1496. // begins with the indicated state. Returns true if at
  1497. // least one cycle is found, false if this state is not
  1498. // part of any cycles. If a cycle is found and
  1499. // cycle_desc is not NULL, then cycle_desc is filled in
  1500. // with the list of the steps of the cycle, in reverse
  1501. // order.
  1502. ////////////////////////////////////////////////////////////////////
  1503. bool RenderState::
  1504. r_detect_cycles(const RenderState *start_state,
  1505. const RenderState *current_state,
  1506. int length, UpdateSeq this_seq,
  1507. RenderState::CompositionCycleDesc *cycle_desc) {
  1508. if (current_state->_cycle_detect == this_seq) {
  1509. // We've already seen this state; therefore, we've found a cycle.
  1510. // However, we only care about cycles that return to the starting
  1511. // state and involve more than two steps. If only one or two
  1512. // nodes are involved, it doesn't represent a memory leak, so no
  1513. // problem there.
  1514. return (current_state == start_state && length > 2);
  1515. }
  1516. ((RenderState *)current_state)->_cycle_detect = this_seq;
  1517. int i;
  1518. int cache_size = current_state->_composition_cache.get_size();
  1519. for (i = 0; i < cache_size; ++i) {
  1520. if (current_state->_composition_cache.has_element(i)) {
  1521. const RenderState *result = current_state->_composition_cache.get_data(i)._result;
  1522. if (result != (const RenderState *)NULL) {
  1523. if (r_detect_cycles(start_state, result, length + 1,
  1524. this_seq, cycle_desc)) {
  1525. // Cycle detected.
  1526. if (cycle_desc != (CompositionCycleDesc *)NULL) {
  1527. const RenderState *other = current_state->_composition_cache.get_key(i);
  1528. CompositionCycleDescEntry entry(other, result, false);
  1529. cycle_desc->push_back(entry);
  1530. }
  1531. return true;
  1532. }
  1533. }
  1534. }
  1535. }
  1536. cache_size = current_state->_invert_composition_cache.get_size();
  1537. for (i = 0; i < cache_size; ++i) {
  1538. if (current_state->_invert_composition_cache.has_element(i)) {
  1539. const RenderState *result = current_state->_invert_composition_cache.get_data(i)._result;
  1540. if (result != (const RenderState *)NULL) {
  1541. if (r_detect_cycles(start_state, result, length + 1,
  1542. this_seq, cycle_desc)) {
  1543. // Cycle detected.
  1544. if (cycle_desc != (CompositionCycleDesc *)NULL) {
  1545. const RenderState *other = current_state->_invert_composition_cache.get_key(i);
  1546. CompositionCycleDescEntry entry(other, result, true);
  1547. cycle_desc->push_back(entry);
  1548. }
  1549. return true;
  1550. }
  1551. }
  1552. }
  1553. }
  1554. // No cycle detected.
  1555. return false;
  1556. }
  1557. ////////////////////////////////////////////////////////////////////
  1558. // Function: RenderState::r_detect_reverse_cycles
  1559. // Access: Private, Static
  1560. // Description: Works the same as r_detect_cycles, but checks for
  1561. // cycles in the reverse direction along the cache
  1562. // chain. (A cycle may appear in either direction, and
  1563. // we must check both.)
  1564. ////////////////////////////////////////////////////////////////////
  1565. bool RenderState::
  1566. r_detect_reverse_cycles(const RenderState *start_state,
  1567. const RenderState *current_state,
  1568. int length, UpdateSeq this_seq,
  1569. RenderState::CompositionCycleDesc *cycle_desc) {
  1570. if (current_state->_cycle_detect == this_seq) {
  1571. // We've already seen this state; therefore, we've found a cycle.
  1572. // However, we only care about cycles that return to the starting
  1573. // state and involve more than two steps. If only one or two
  1574. // nodes are involved, it doesn't represent a memory leak, so no
  1575. // problem there.
  1576. return (current_state == start_state && length > 2);
  1577. }
  1578. ((RenderState *)current_state)->_cycle_detect = this_seq;
  1579. int i;
  1580. int cache_size = current_state->_composition_cache.get_size();
  1581. for (i = 0; i < cache_size; ++i) {
  1582. if (current_state->_composition_cache.has_element(i)) {
  1583. const RenderState *other = current_state->_composition_cache.get_key(i);
  1584. if (other != current_state) {
  1585. int oi = other->_composition_cache.find(current_state);
  1586. nassertr(oi != -1, false);
  1587. const RenderState *result = other->_composition_cache.get_data(oi)._result;
  1588. if (result != (const RenderState *)NULL) {
  1589. if (r_detect_reverse_cycles(start_state, result, length + 1,
  1590. this_seq, cycle_desc)) {
  1591. // Cycle detected.
  1592. if (cycle_desc != (CompositionCycleDesc *)NULL) {
  1593. const RenderState *other = current_state->_composition_cache.get_key(i);
  1594. CompositionCycleDescEntry entry(other, result, false);
  1595. cycle_desc->push_back(entry);
  1596. }
  1597. return true;
  1598. }
  1599. }
  1600. }
  1601. }
  1602. }
  1603. cache_size = current_state->_invert_composition_cache.get_size();
  1604. for (i = 0; i < cache_size; ++i) {
  1605. if (current_state->_invert_composition_cache.has_element(i)) {
  1606. const RenderState *other = current_state->_invert_composition_cache.get_key(i);
  1607. if (other != current_state) {
  1608. int oi = other->_invert_composition_cache.find(current_state);
  1609. nassertr(oi != -1, false);
  1610. const RenderState *result = other->_invert_composition_cache.get_data(oi)._result;
  1611. if (result != (const RenderState *)NULL) {
  1612. if (r_detect_reverse_cycles(start_state, result, length + 1,
  1613. this_seq, cycle_desc)) {
  1614. // Cycle detected.
  1615. if (cycle_desc != (CompositionCycleDesc *)NULL) {
  1616. const RenderState *other = current_state->_invert_composition_cache.get_key(i);
  1617. CompositionCycleDescEntry entry(other, result, false);
  1618. cycle_desc->push_back(entry);
  1619. }
  1620. return true;
  1621. }
  1622. }
  1623. }
  1624. }
  1625. }
  1626. // No cycle detected.
  1627. return false;
  1628. }
  1629. ////////////////////////////////////////////////////////////////////
  1630. // Function: RenderState::release_new
  1631. // Access: Private
  1632. // Description: This inverse of return_new, this releases this object
  1633. // from the global RenderState table.
  1634. //
  1635. // You must already be holding _states_lock before you
  1636. // call this method.
  1637. ////////////////////////////////////////////////////////////////////
  1638. void RenderState::
  1639. release_new() {
  1640. nassertv(_states_lock->debug_is_locked());
  1641. if (_saved_entry != -1) {
  1642. //nassertv(_states->find(this) == _saved_entry);
  1643. _saved_entry = _states->find(this);
  1644. _states->remove_element(_saved_entry);
  1645. _saved_entry = -1;
  1646. }
  1647. }
  1648. ////////////////////////////////////////////////////////////////////
  1649. // Function: RenderState::remove_cache_pointers
  1650. // Access: Private
  1651. // Description: Remove all pointers within the cache from and to this
  1652. // particular RenderState. The pointers to this
  1653. // object may be scattered around in the various
  1654. // CompositionCaches from other RenderState objects.
  1655. //
  1656. // You must already be holding _states_lock before you
  1657. // call this method.
  1658. ////////////////////////////////////////////////////////////////////
  1659. void RenderState::
  1660. remove_cache_pointers() {
  1661. nassertv(_states_lock->debug_is_locked());
  1662. // First, make sure the _auto_shader_state cache pointer is cleared.
  1663. if (_auto_shader_state != (const RenderState *)NULL) {
  1664. if (_auto_shader_state != this) {
  1665. cache_unref_delete(_auto_shader_state);
  1666. }
  1667. _auto_shader_state = NULL;
  1668. }
  1669. // Fortunately, since we added CompositionCache records in pairs, we
  1670. // know exactly the set of RenderState objects that have us in their
  1671. // cache: it's the same set of RenderState objects that we have in
  1672. // our own cache.
  1673. // We do need to put considerable thought into this loop, because as
  1674. // we clear out cache entries we'll cause other RenderState
  1675. // objects to destruct, which could cause things to get pulled out
  1676. // of our own _composition_cache map. We want to allow this (so
  1677. // that we don't encounter any just-destructed pointers in our
  1678. // cache), but we don't want to get bitten by this cascading effect.
  1679. // Instead of walking through the map from beginning to end,
  1680. // therefore, we just pull out the first one each time, and erase
  1681. // it.
  1682. #ifdef DO_PSTATS
  1683. if (_composition_cache.is_empty() && _invert_composition_cache.is_empty()) {
  1684. return;
  1685. }
  1686. PStatTimer timer(_cache_update_pcollector);
  1687. #endif // DO_PSTATS
  1688. // There are lots of ways to do this loop wrong. Be very careful if
  1689. // you need to modify it for any reason.
  1690. int i = 0;
  1691. while (!_composition_cache.is_empty()) {
  1692. // Scan for the next used slot in the table.
  1693. while (!_composition_cache.has_element(i)) {
  1694. ++i;
  1695. }
  1696. // It is possible that the "other" RenderState object is
  1697. // currently within its own destructor. We therefore can't use a
  1698. // PT() to hold its pointer; that could end up calling its
  1699. // destructor twice. Fortunately, we don't need to hold its
  1700. // reference count to ensure it doesn't destruct while we process
  1701. // this loop; as long as we ensure that no *other* RenderState
  1702. // objects destruct, there will be no reason for that one to.
  1703. RenderState *other = (RenderState *)_composition_cache.get_key(i);
  1704. // We hold a copy of the composition result so we can dereference
  1705. // it later.
  1706. Composition comp = _composition_cache.get_data(i);
  1707. // Now we can remove the element from our cache. We do this now,
  1708. // rather than later, before any other RenderState objects have
  1709. // had a chance to destruct, so we are confident that our iterator
  1710. // is still valid.
  1711. _composition_cache.remove_element(i);
  1712. _cache_stats.add_total_size(-1);
  1713. _cache_stats.inc_dels();
  1714. if (other != this) {
  1715. int oi = other->_composition_cache.find(this);
  1716. // We may or may not still be listed in the other's cache (it
  1717. // might be halfway through pulling entries out, from within its
  1718. // own destructor).
  1719. if (oi != -1) {
  1720. // Hold a copy of the other composition result, too.
  1721. Composition ocomp = other->_composition_cache.get_data(oi);
  1722. other->_composition_cache.remove_element(oi);
  1723. _cache_stats.add_total_size(-1);
  1724. _cache_stats.inc_dels();
  1725. // It's finally safe to let our held pointers go away. This may
  1726. // have cascading effects as other RenderState objects are
  1727. // destructed, but there will be no harm done if they destruct
  1728. // now.
  1729. if (ocomp._result != (const RenderState *)NULL && ocomp._result != other) {
  1730. cache_unref_delete(ocomp._result);
  1731. }
  1732. }
  1733. }
  1734. // It's finally safe to let our held pointers go away. (See
  1735. // comment above.)
  1736. if (comp._result != (const RenderState *)NULL && comp._result != this) {
  1737. cache_unref_delete(comp._result);
  1738. }
  1739. }
  1740. // A similar bit of code for the invert cache.
  1741. i = 0;
  1742. while (!_invert_composition_cache.is_empty()) {
  1743. while (!_invert_composition_cache.has_element(i)) {
  1744. ++i;
  1745. }
  1746. RenderState *other = (RenderState *)_invert_composition_cache.get_key(i);
  1747. nassertv(other != this);
  1748. Composition comp = _invert_composition_cache.get_data(i);
  1749. _invert_composition_cache.remove_element(i);
  1750. _cache_stats.add_total_size(-1);
  1751. _cache_stats.inc_dels();
  1752. if (other != this) {
  1753. int oi = other->_invert_composition_cache.find(this);
  1754. if (oi != -1) {
  1755. Composition ocomp = other->_invert_composition_cache.get_data(oi);
  1756. other->_invert_composition_cache.remove_element(oi);
  1757. _cache_stats.add_total_size(-1);
  1758. _cache_stats.inc_dels();
  1759. if (ocomp._result != (const RenderState *)NULL && ocomp._result != other) {
  1760. cache_unref_delete(ocomp._result);
  1761. }
  1762. }
  1763. }
  1764. if (comp._result != (const RenderState *)NULL && comp._result != this) {
  1765. cache_unref_delete(comp._result);
  1766. }
  1767. }
  1768. }
  1769. ////////////////////////////////////////////////////////////////////
  1770. // Function: RenderState::determine_bin_index
  1771. // Access: Private
  1772. // Description: This is the private implementation of
  1773. // get_bin_index() and get_draw_order().
  1774. ////////////////////////////////////////////////////////////////////
  1775. void RenderState::
  1776. determine_bin_index() {
  1777. LightMutexHolder holder(_lock);
  1778. if ((_flags & F_checked_bin_index) != 0) {
  1779. // Someone else checked it first.
  1780. return;
  1781. }
  1782. string bin_name;
  1783. _draw_order = 0;
  1784. const CullBinAttrib *bin = DCAST(CullBinAttrib, get_attrib(CullBinAttrib::get_class_slot()));
  1785. if (bin != (const CullBinAttrib *)NULL) {
  1786. bin_name = bin->get_bin_name();
  1787. _draw_order = bin->get_draw_order();
  1788. }
  1789. if (bin_name.empty()) {
  1790. // No explicit bin is specified; put in the in the default bin,
  1791. // either opaque or transparent, based on the transparency
  1792. // setting.
  1793. bin_name = "opaque";
  1794. const TransparencyAttrib *transparency = DCAST(TransparencyAttrib, get_attrib(TransparencyAttrib::get_class_slot()));
  1795. if (transparency != (const TransparencyAttrib *)NULL) {
  1796. switch (transparency->get_mode()) {
  1797. case TransparencyAttrib::M_alpha:
  1798. case TransparencyAttrib::M_dual:
  1799. // These transparency modes require special back-to-front sorting.
  1800. bin_name = "transparent";
  1801. break;
  1802. default:
  1803. break;
  1804. }
  1805. }
  1806. }
  1807. CullBinManager *bin_manager = CullBinManager::get_global_ptr();
  1808. _bin_index = bin_manager->find_bin(bin_name);
  1809. if (_bin_index == -1) {
  1810. pgraph_cat.warning()
  1811. << "No bin named " << bin_name << "; creating default bin.\n";
  1812. _bin_index = bin_manager->add_bin(bin_name, CullBinManager::BT_unsorted, 0);
  1813. }
  1814. _flags |= F_checked_bin_index;
  1815. }
  1816. ////////////////////////////////////////////////////////////////////
  1817. // Function: RenderState::determine_cull_callback
  1818. // Access: Private
  1819. // Description: This is the private implementation of has_cull_callback().
  1820. ////////////////////////////////////////////////////////////////////
  1821. void RenderState::
  1822. determine_cull_callback() {
  1823. LightMutexHolder holder(_lock);
  1824. if ((_flags & F_checked_cull_callback) != 0) {
  1825. // Someone else checked it first.
  1826. return;
  1827. }
  1828. SlotMask mask = _filled_slots;
  1829. int slot = mask.get_lowest_on_bit();
  1830. while (slot >= 0) {
  1831. const Attribute &attrib = _attributes[slot];
  1832. nassertv(attrib._attrib != (RenderAttrib *)NULL);
  1833. if (attrib._attrib->has_cull_callback()) {
  1834. _flags |= F_has_cull_callback;
  1835. break;
  1836. }
  1837. mask.clear_bit(slot);
  1838. slot = mask.get_lowest_on_bit();
  1839. }
  1840. _flags |= F_checked_cull_callback;
  1841. }
  1842. ////////////////////////////////////////////////////////////////////
  1843. // Function: RenderState::fill_default
  1844. // Access: Private
  1845. // Description: Fills up the state with all of the default attribs.
  1846. ////////////////////////////////////////////////////////////////////
  1847. void RenderState::
  1848. fill_default() {
  1849. RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
  1850. int num_slots = reg->get_num_slots();
  1851. for (int slot = 1; slot < num_slots; ++slot) {
  1852. _attributes[slot].set(reg->get_slot_default(slot), 0);
  1853. _filled_slots.set_bit(slot);
  1854. }
  1855. }
  1856. ////////////////////////////////////////////////////////////////////
  1857. // Function: RenderState::update_pstats
  1858. // Access: Private
  1859. // Description: Moves the RenderState object from one PStats category
  1860. // to another, so that we can track in PStats how many
  1861. // pointers are held by nodes, and how many are held in
  1862. // the cache only.
  1863. ////////////////////////////////////////////////////////////////////
  1864. void RenderState::
  1865. update_pstats(int old_referenced_bits, int new_referenced_bits) {
  1866. #ifdef DO_PSTATS
  1867. if ((old_referenced_bits & R_node) != 0) {
  1868. _node_counter.sub_level(1);
  1869. } else if ((old_referenced_bits & R_cache) != 0) {
  1870. _cache_counter.sub_level(1);
  1871. }
  1872. if ((new_referenced_bits & R_node) != 0) {
  1873. _node_counter.add_level(1);
  1874. } else if ((new_referenced_bits & R_cache) != 0) {
  1875. _cache_counter.add_level(1);
  1876. }
  1877. #endif // DO_PSTATS
  1878. }
  1879. ////////////////////////////////////////////////////////////////////
  1880. // Function: RenderState::init_states
  1881. // Access: Public, Static
  1882. // Description: Make sure the global _states map is allocated. This
  1883. // only has to be done once. We could make this map
  1884. // static, but then we run into problems if anyone
  1885. // creates a RenderState object at static init time;
  1886. // it also seems to cause problems when the Panda shared
  1887. // library is unloaded at application exit time.
  1888. ////////////////////////////////////////////////////////////////////
  1889. void RenderState::
  1890. init_states() {
  1891. _states = new States;
  1892. // TODO: we should have a global Panda mutex to allow us to safely
  1893. // create _states_lock without a startup race condition. For the
  1894. // meantime, this is OK because we guarantee that this method is
  1895. // called at static init time, presumably when there is still only
  1896. // one thread in the world.
  1897. _states_lock = new LightReMutex("RenderState::_states_lock");
  1898. _cache_stats.init();
  1899. nassertv(Thread::get_current_thread() == Thread::get_main_thread());
  1900. // Initialize the empty state object as well. It is used so often
  1901. // that it is declared globally, and lives forever.
  1902. RenderState *state = new RenderState;
  1903. state->local_object();
  1904. state->_saved_entry = _states->store(state, Empty());
  1905. _empty_state = state;
  1906. }
  1907. ////////////////////////////////////////////////////////////////////
  1908. // Function: RenderState::register_with_read_factory
  1909. // Access: Public, Static
  1910. // Description: Tells the BamReader how to create objects of type
  1911. // RenderState.
  1912. ////////////////////////////////////////////////////////////////////
  1913. void RenderState::
  1914. register_with_read_factory() {
  1915. BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
  1916. }
  1917. ////////////////////////////////////////////////////////////////////
  1918. // Function: RenderState::write_datagram
  1919. // Access: Public, Virtual
  1920. // Description: Writes the contents of this object to the datagram
  1921. // for shipping out to a Bam file.
  1922. ////////////////////////////////////////////////////////////////////
  1923. void RenderState::
  1924. write_datagram(BamWriter *manager, Datagram &dg) {
  1925. TypedWritable::write_datagram(manager, dg);
  1926. int num_attribs = _filled_slots.get_num_on_bits();
  1927. nassertv(num_attribs == (int)(PN_uint16)num_attribs);
  1928. dg.add_uint16(num_attribs);
  1929. // **** We should smarten up the writing of the override
  1930. // number--most of the time these will all be zero.
  1931. SlotMask mask = _filled_slots;
  1932. int slot = mask.get_lowest_on_bit();
  1933. while (slot >= 0) {
  1934. const Attribute &attrib = _attributes[slot];
  1935. nassertv(attrib._attrib != (RenderAttrib *)NULL);
  1936. manager->write_pointer(dg, attrib._attrib);
  1937. dg.add_int32(attrib._override);
  1938. mask.clear_bit(slot);
  1939. slot = mask.get_lowest_on_bit();
  1940. }
  1941. }
  1942. ////////////////////////////////////////////////////////////////////
  1943. // Function: RenderState::complete_pointers
  1944. // Access: Public, Virtual
  1945. // Description: Receives an array of pointers, one for each time
  1946. // manager->read_pointer() was called in fillin().
  1947. // Returns the number of pointers processed.
  1948. ////////////////////////////////////////////////////////////////////
  1949. int RenderState::
  1950. complete_pointers(TypedWritable **p_list, BamReader *manager) {
  1951. int pi = TypedWritable::complete_pointers(p_list, manager);
  1952. int num_attribs = 0;
  1953. RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
  1954. for (size_t i = 0; i < (*_read_overrides).size(); ++i) {
  1955. int override = (*_read_overrides)[i];
  1956. RenderAttrib *attrib = DCAST(RenderAttrib, p_list[pi++]);
  1957. if (attrib != (RenderAttrib *)NULL) {
  1958. int slot = attrib->get_slot();
  1959. if (slot > 0 && slot < reg->get_max_slots()) {
  1960. _attributes[slot].set(attrib, override);
  1961. _filled_slots.set_bit(slot);
  1962. ++num_attribs;
  1963. }
  1964. }
  1965. }
  1966. delete _read_overrides;
  1967. _read_overrides = NULL;
  1968. return pi;
  1969. }
  1970. ////////////////////////////////////////////////////////////////////
  1971. // Function: RenderState::change_this
  1972. // Access: Public, Static
  1973. // Description: Called immediately after complete_pointers(), this
  1974. // gives the object a chance to adjust its own pointer
  1975. // if desired. Most objects don't change pointers after
  1976. // completion, but some need to.
  1977. //
  1978. // Once this function has been called, the old pointer
  1979. // will no longer be accessed.
  1980. ////////////////////////////////////////////////////////////////////
  1981. TypedWritable *RenderState::
  1982. change_this(TypedWritable *old_ptr, BamReader *manager) {
  1983. // First, uniquify the pointer.
  1984. RenderState *state = DCAST(RenderState, old_ptr);
  1985. CPT(RenderState) pointer = return_unique(state);
  1986. // But now we have a problem, since we have to hold the reference
  1987. // count and there's no way to return a TypedWritable while still
  1988. // holding the reference count! We work around this by explicitly
  1989. // upping the count, and also setting a finalize() callback to down
  1990. // it later.
  1991. if (pointer == state) {
  1992. pointer->ref();
  1993. manager->register_finalize(state);
  1994. }
  1995. // We have to cast the pointer back to non-const, because the bam
  1996. // reader expects that.
  1997. return (RenderState *)pointer.p();
  1998. }
  1999. ////////////////////////////////////////////////////////////////////
  2000. // Function: RenderState::finalize
  2001. // Access: Public, Virtual
  2002. // Description: Called by the BamReader to perform any final actions
  2003. // needed for setting up the object after all objects
  2004. // have been read and all pointers have been completed.
  2005. ////////////////////////////////////////////////////////////////////
  2006. void RenderState::
  2007. finalize(BamReader *) {
  2008. // Unref the pointer that we explicitly reffed in change_this().
  2009. unref();
  2010. // We should never get back to zero after unreffing our own count,
  2011. // because we expect to have been stored in a pointer somewhere. If
  2012. // we do get to zero, it's a memory leak; the way to avoid this is
  2013. // to call unref_delete() above instead of unref(), but this is
  2014. // dangerous to do from within a virtual function.
  2015. nassertv(get_ref_count() != 0);
  2016. }
  2017. ////////////////////////////////////////////////////////////////////
  2018. // Function: RenderState::make_from_bam
  2019. // Access: Protected, Static
  2020. // Description: This function is called by the BamReader's factory
  2021. // when a new object of type RenderState is encountered
  2022. // in the Bam file. It should create the RenderState
  2023. // and extract its information from the file.
  2024. ////////////////////////////////////////////////////////////////////
  2025. TypedWritable *RenderState::
  2026. make_from_bam(const FactoryParams &params) {
  2027. RenderState *state = new RenderState;
  2028. DatagramIterator scan;
  2029. BamReader *manager;
  2030. parse_params(params, scan, manager);
  2031. state->fillin(scan, manager);
  2032. manager->register_change_this(change_this, state);
  2033. return state;
  2034. }
  2035. ////////////////////////////////////////////////////////////////////
  2036. // Function: RenderState::fillin
  2037. // Access: Protected
  2038. // Description: This internal function is called by make_from_bam to
  2039. // read in all of the relevant data from the BamFile for
  2040. // the new RenderState.
  2041. ////////////////////////////////////////////////////////////////////
  2042. void RenderState::
  2043. fillin(DatagramIterator &scan, BamReader *manager) {
  2044. TypedWritable::fillin(scan, manager);
  2045. int num_attribs = scan.get_uint16();
  2046. _read_overrides = new vector_int;
  2047. (*_read_overrides).reserve(num_attribs);
  2048. for (int i = 0; i < num_attribs; ++i) {
  2049. manager->read_pointer(scan);
  2050. int override = scan.get_int32();
  2051. (*_read_overrides).push_back(override);
  2052. }
  2053. }