renderState_ext.cxx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file renderState_ext.cxx
  10. * @author CFSworks
  11. * @date 2014-03-31
  12. */
  13. #include "renderState_ext.h"
  14. #ifdef HAVE_PYTHON
  15. /**
  16. * Returns a list of 2-tuples that represents the composition cache. For each
  17. * tuple in the list, the first element is the source render, and the second
  18. * is the result render. If both are None, there is no entry in the cache at
  19. * that slot.
  20. *
  21. * In general, a->compose(source) == result.
  22. *
  23. * This has no practical value other than for examining the cache for
  24. * performance analysis.
  25. */
  26. PyObject *Extension<RenderState>::
  27. get_composition_cache() const {
  28. extern struct Dtool_PyTypedObject Dtool_RenderState;
  29. LightReMutexHolder holder(*RenderState::_states_lock);
  30. size_t cache_size = _this->_composition_cache.get_num_entries();
  31. PyObject *list = PyList_New(cache_size);
  32. for (size_t i = 0; i < cache_size; ++i) {
  33. PyObject *tuple = PyTuple_New(2);
  34. PyObject *a, *b;
  35. const RenderState *source = _this->_composition_cache.get_key(i);
  36. if (source == nullptr) {
  37. a = Py_None;
  38. Py_INCREF(a);
  39. } else {
  40. source->ref();
  41. a = DTool_CreatePyInstanceTyped((void *)source, Dtool_RenderState,
  42. true, true, source->get_type_index());
  43. }
  44. const RenderState *result = _this->_composition_cache.get_data(i)._result;
  45. if (result == nullptr) {
  46. b = Py_None;
  47. Py_INCREF(b);
  48. } else {
  49. result->ref();
  50. b = DTool_CreatePyInstanceTyped((void *)result, Dtool_RenderState,
  51. true, true, result->get_type_index());
  52. }
  53. PyTuple_SET_ITEM(tuple, 0, a);
  54. PyTuple_SET_ITEM(tuple, 1, b);
  55. PyList_SET_ITEM(list, i, tuple);
  56. }
  57. return list;
  58. }
  59. /**
  60. * Returns a list of 2-tuples that represents the invert_composition cache.
  61. * For each tuple in the list, the first element is the source render, and the
  62. * second is the result render. If both are None, there is no entry in the
  63. * cache at that slot.
  64. *
  65. * In general, a->invert_compose(source) == result.
  66. *
  67. * This has no practical value other than for examining the cache for
  68. * performance analysis.
  69. */
  70. PyObject *Extension<RenderState>::
  71. get_invert_composition_cache() const {
  72. extern struct Dtool_PyTypedObject Dtool_RenderState;
  73. LightReMutexHolder holder(*RenderState::_states_lock);
  74. size_t cache_size = _this->_invert_composition_cache.get_num_entries();
  75. PyObject *list = PyList_New(cache_size);
  76. for (size_t i = 0; i < cache_size; ++i) {
  77. PyObject *tuple = PyTuple_New(2);
  78. PyObject *a, *b;
  79. const RenderState *source = _this->_invert_composition_cache.get_key(i);
  80. if (source == nullptr) {
  81. a = Py_None;
  82. Py_INCREF(a);
  83. } else {
  84. source->ref();
  85. a = DTool_CreatePyInstanceTyped((void *)source, Dtool_RenderState,
  86. true, true, source->get_type_index());
  87. }
  88. const RenderState *result = _this->_invert_composition_cache.get_data(i)._result;
  89. if (result == nullptr) {
  90. b = Py_None;
  91. Py_INCREF(b);
  92. } else {
  93. result->ref();
  94. b = DTool_CreatePyInstanceTyped((void *)result, Dtool_RenderState,
  95. true, true, result->get_type_index());
  96. }
  97. PyTuple_SET_ITEM(tuple, 0, a);
  98. PyTuple_SET_ITEM(tuple, 1, b);
  99. PyList_SET_ITEM(list, i, tuple);
  100. }
  101. return list;
  102. }
  103. /**
  104. * Returns a list of all of the RenderState objects in the state cache. The
  105. * order of elements in this cache is arbitrary.
  106. */
  107. PyObject *Extension<RenderState>::
  108. get_states() {
  109. extern struct Dtool_PyTypedObject Dtool_RenderState;
  110. if (RenderState::_states == nullptr) {
  111. return PyList_New(0);
  112. }
  113. LightReMutexHolder holder(*RenderState::_states_lock);
  114. size_t num_states = RenderState::_states->get_num_entries();
  115. PyObject *list = PyList_New(num_states);
  116. size_t i = 0;
  117. size_t size = RenderState::_states->get_num_entries();
  118. for (size_t si = 0; si < size; ++si) {
  119. const RenderState *state = RenderState::_states->get_key(si);
  120. state->ref();
  121. PyObject *a =
  122. DTool_CreatePyInstanceTyped((void *)state, Dtool_RenderState,
  123. true, true, state->get_type_index());
  124. nassertr(i < num_states, list);
  125. PyList_SET_ITEM(list, i, a);
  126. ++i;
  127. }
  128. nassertr(i == num_states, list);
  129. return list;
  130. }
  131. /**
  132. * Returns a list of all of the "unused" RenderState objects in the state
  133. * cache. See get_num_unused_states().
  134. */
  135. PyObject *Extension<RenderState>::
  136. get_unused_states() {
  137. extern struct Dtool_PyTypedObject Dtool_RenderState;
  138. if (RenderState::_states == nullptr) {
  139. return PyList_New(0);
  140. }
  141. LightReMutexHolder holder(*RenderState::_states_lock);
  142. PyObject *list = PyList_New(0);
  143. size_t size = RenderState::_states->get_num_entries();
  144. for (size_t si = 0; si < size; ++si) {
  145. const RenderState *state = RenderState::_states->get_key(si);
  146. if (state->get_cache_ref_count() == state->get_ref_count()) {
  147. state->ref();
  148. PyObject *a =
  149. DTool_CreatePyInstanceTyped((void *)state, Dtool_RenderState,
  150. true, true, state->get_type_index());
  151. PyList_Append(list, a);
  152. Py_DECREF(a);
  153. }
  154. }
  155. return list;
  156. }
  157. #endif // HAVE_PYTHON