30 TypeHandle PreparedGraphicsObjects::EnqueuedObject::_type_handle;
32 int PreparedGraphicsObjects::_name_index = 0;
37 PreparedGraphicsObjects::
38 PreparedGraphicsObjects() :
39 _lock(
"PreparedGraphicsObjects::_lock"),
41 _vertex_buffer_cache_size(0),
42 _index_buffer_cache_size(0),
43 _texture_residency(_name,
"texture"),
44 _vbuffer_residency(_name,
"vbuffer"),
45 _ibuffer_residency(_name,
"ibuffer"),
46 _sbuffer_residency(_name,
"sbuffer"),
47 _graphics_memory_lru(
"graphics_memory_lru", graphics_memory_limit),
48 _sampler_object_lru(
"sampler_object_lru", sampler_object_limit)
53 _support_released_buffer_cache =
false;
59 PreparedGraphicsObjects::
60 ~PreparedGraphicsObjects() {
69 Textures::iterator tci;
70 for (tci = _released_textures.begin();
71 tci != _released_textures.end();
76 _released_textures.clear();
79 ReleasedSamplers::iterator ssci;
80 for (ssci = _released_samplers.begin();
81 ssci != _released_samplers.end();
86 _released_samplers.clear();
90 for (gci = _released_geoms.begin();
91 gci != _released_geoms.end();
96 _released_geoms.clear();
99 Shaders::iterator sci;
100 for (sci = _released_shaders.begin();
101 sci != _released_shaders.end();
106 _released_shaders.clear();
109 Buffers::iterator vbci;
110 for (vbci = _released_vertex_buffers.begin();
111 vbci != _released_vertex_buffers.end();
116 _released_vertex_buffers.clear();
119 Buffers::iterator ibci;
120 for (ibci = _released_index_buffers.begin();
121 ibci != _released_index_buffers.end();
126 _released_index_buffers.clear();
129 Buffers::iterator bci;
130 for (bci = _released_shader_buffers.begin();
131 bci != _released_shader_buffers.end();
136 _released_shader_buffers.clear();
156 throw_event(
"graphics_memory_limit_changed");
166 _graphics_memory_lru.write(out, 0);
175 out <<
"Textures:\n";
176 _texture_residency.write(out, 2);
178 out <<
"\nVertex buffers:\n";
179 _vbuffer_residency.write(out, 2);
181 out <<
"\nIndex buffers:\n";
182 _ibuffer_residency.write(out, 2);
184 out <<
"\nShader buffers:\n";
185 _sbuffer_residency.write(out, 2);
196 _enqueued_textures.insert(EnqueuedTextures::value_type(tex,
nullptr));
204 enqueue_texture_future(
Texture *tex) {
207 std::pair<EnqueuedTextures::iterator, bool> result =
208 _enqueued_textures.insert(EnqueuedTextures::value_type(tex,
nullptr));
209 if (result.first->second ==
nullptr) {
210 result.first->second =
new EnqueuedObject(
this, tex);
212 PT(EnqueuedObject) fut = result.first->second;
213 nassertr(!fut->cancelled(), fut)
224 EnqueuedTextures::const_iterator qi = _enqueued_textures.find((
Texture *)tex);
225 return (qi != _enqueued_textures.end());
241 EnqueuedTextures::iterator qi = _enqueued_textures.find(tex);
242 if (qi != _enqueued_textures.end()) {
243 if (qi->second !=
nullptr) {
244 qi->second->notify_removed();
246 _enqueued_textures.erase(qi);
277 tc->_object =
nullptr;
279 bool removed = (_prepared_textures.erase(tc) != 0);
282 _released_textures.insert(tc);
303 int num_textures = (int)_prepared_textures.size() + (int)_enqueued_textures.size();
305 Textures::iterator tci;
306 for (tci = _prepared_textures.begin();
307 tci != _prepared_textures.end();
311 tc->_object =
nullptr;
313 _released_textures.insert(tc);
316 _prepared_textures.clear();
319 EnqueuedTextures::iterator qti;
320 for (qti = _enqueued_textures.begin();
321 qti != _enqueued_textures.end();
323 if (qti->second !=
nullptr) {
324 qti->second->notify_removed();
328 _enqueued_textures.clear();
339 return _enqueued_textures.size();
347 return _prepared_textures.size();
376 bool prepared = _prepared_textures.insert(tc).second;
377 nassertr(prepared, tc);
391 _enqueued_samplers.insert(sampler);
401 EnqueuedSamplers::const_iterator qi = _enqueued_samplers.find(sampler);
402 return (qi != _enqueued_samplers.end());
418 EnqueuedSamplers::iterator qi = _enqueued_samplers.find(sampler);
419 if (qi != _enqueued_samplers.end()) {
420 _enqueued_samplers.erase(qi);
433 PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
434 return (it != _prepared_samplers.end());
447 _released_samplers.insert(sc);
458 PreparedSamplers::iterator it = _prepared_samplers.find(sampler);
459 if (it != _prepared_samplers.end()) {
460 _released_samplers.insert(it->second);
461 _prepared_samplers.erase(it);
464 _enqueued_samplers.erase(sampler);
475 int num_samplers = (int)_prepared_samplers.size() + (int)_enqueued_samplers.size();
477 PreparedSamplers::iterator sci;
478 for (sci = _prepared_samplers.begin();
479 sci != _prepared_samplers.end();
481 _released_samplers.insert(sci->second);
484 _prepared_samplers.clear();
485 _enqueued_samplers.clear();
496 return _enqueued_samplers.size();
504 return _prepared_samplers.size();
527 PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
528 if (it != _prepared_samplers.end()) {
536 _prepared_samplers[sampler] = sc;
550 _enqueued_geoms.insert(geom);
560 EnqueuedGeoms::const_iterator qi = _enqueued_geoms.find((
Geom *)geom);
561 return (qi != _enqueued_geoms.end());
577 EnqueuedGeoms::iterator qi = _enqueued_geoms.find(geom);
578 if (qi != _enqueued_geoms.end()) {
579 _enqueued_geoms.erase(qi);
607 gc->_geom->clear_prepared(
this);
613 bool removed = (_prepared_geoms.erase(gc) != 0);
616 _released_geoms.insert(gc);
628 int num_geoms = (int)_prepared_geoms.size() + (int)_enqueued_geoms.size();
631 for (gci = _prepared_geoms.begin();
632 gci != _prepared_geoms.end();
635 gc->_geom->clear_prepared(
this);
638 _released_geoms.insert(gc);
641 _prepared_geoms.clear();
642 _enqueued_geoms.clear();
653 return _enqueued_geoms.size();
661 return _prepared_geoms.size();
690 bool prepared = _prepared_geoms.insert(gc).second;
691 nassertr(prepared, gc);
705 _enqueued_shaders.insert(EnqueuedShaders::value_type(shader,
nullptr));
713 enqueue_shader_future(
Shader *shader) {
716 std::pair<EnqueuedShaders::iterator, bool> result =
717 _enqueued_shaders.insert(EnqueuedShaders::value_type(shader,
nullptr));
718 if (result.first->second ==
nullptr) {
719 result.first->second =
new EnqueuedObject(
this, shader);
721 PT(EnqueuedObject) fut = result.first->second;
722 nassertr(!fut->cancelled(), fut)
733 EnqueuedShaders::const_iterator qi = _enqueued_shaders.find((
Shader *)shader);
734 return (qi != _enqueued_shaders.end());
750 EnqueuedShaders::iterator qi = _enqueued_shaders.find(se);
751 if (qi != _enqueued_shaders.end()) {
752 if (qi->second !=
nullptr) {
753 qi->second->notify_removed();
755 _enqueued_shaders.erase(qi);
782 sc->_shader->clear_prepared(
this);
786 sc->_shader =
nullptr;
788 bool removed = (_prepared_shaders.erase(sc) != 0);
791 _released_shaders.insert(sc);
803 int num_shaders = (int)_prepared_shaders.size() + (int)_enqueued_shaders.size();
805 Shaders::iterator sci;
806 for (sci = _prepared_shaders.begin();
807 sci != _prepared_shaders.end();
810 sc->_shader->clear_prepared(
this);
811 sc->_shader =
nullptr;
813 _released_shaders.insert(sc);
816 _prepared_shaders.clear();
819 EnqueuedShaders::iterator qsi;
820 for (qsi = _enqueued_shaders.begin();
821 qsi != _enqueued_shaders.end();
823 if (qsi->second !=
nullptr) {
824 qsi->second->notify_removed();
828 _enqueued_shaders.clear();
839 return _enqueued_shaders.size();
847 return _prepared_shaders.size();
876 bool prepared = _prepared_shaders.insert(sc).second;
877 nassertr(prepared, sc);
891 _enqueued_vertex_buffers.insert(data);
902 EnqueuedVertexBuffers::const_iterator qi = _enqueued_vertex_buffers.find((
GeomVertexArrayData *)data);
903 return (qi != _enqueued_vertex_buffers.end());
919 EnqueuedVertexBuffers::iterator qi = _enqueued_vertex_buffers.find(data);
920 if (qi != _enqueued_vertex_buffers.end()) {
921 _enqueued_vertex_buffers.erase(qi);
949 vbc->
get_data()->clear_prepared(
this);
956 vbc->_object =
nullptr;
958 bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
961 if (_support_released_buffer_cache) {
962 cache_unprepared_buffer(vbc, data_size_bytes, usage_hint,
963 _vertex_buffer_cache,
964 _vertex_buffer_cache_lru, _vertex_buffer_cache_size,
965 released_vbuffer_cache_size,
966 _released_vertex_buffers);
968 _released_vertex_buffers.insert(vbc);
981 int num_vertex_buffers = (int)_prepared_vertex_buffers.size() + (int)_enqueued_vertex_buffers.size();
983 Buffers::iterator vbci;
984 for (vbci = _prepared_vertex_buffers.begin();
985 vbci != _prepared_vertex_buffers.end();
988 vbc->
get_data()->clear_prepared(
this);
989 vbc->_object =
nullptr;
991 _released_vertex_buffers.insert(vbc);
994 _prepared_vertex_buffers.clear();
995 _enqueued_vertex_buffers.clear();
998 BufferCache::iterator bci;
999 for (bci = _vertex_buffer_cache.begin();
1000 bci != _vertex_buffer_cache.end();
1003 nassertr(!buffer_list.empty(), num_vertex_buffers);
1004 BufferList::iterator li;
1005 for (li = buffer_list.begin(); li != buffer_list.end(); ++li) {
1007 _released_vertex_buffers.insert(vbc);
1010 _vertex_buffer_cache.clear();
1011 _vertex_buffer_cache_lru.clear();
1012 _vertex_buffer_cache_size = 0;
1014 return num_vertex_buffers;
1023 return _enqueued_vertex_buffers.size();
1032 return _prepared_vertex_buffers.size();
1057 size_t data_size_bytes = data->get_data_size_bytes();
1058 GeomEnums::UsageHint usage_hint = data->get_usage_hint();
1060 get_cached_buffer(data_size_bytes, usage_hint,
1061 _vertex_buffer_cache, _vertex_buffer_cache_lru,
1062 _vertex_buffer_cache_size);
1063 if (vbc !=
nullptr) {
1064 vbc->_object = data;
1070 vbc = gsg->prepare_vertex_buffer(data);
1073 if (vbc !=
nullptr) {
1074 bool prepared = _prepared_vertex_buffers.insert(vbc).second;
1075 nassertr(prepared, vbc);
1089 _enqueued_index_buffers.insert(data);
1100 EnqueuedIndexBuffers::const_iterator qi = _enqueued_index_buffers.find((
GeomPrimitive *)data);
1101 return (qi != _enqueued_index_buffers.end());
1117 EnqueuedIndexBuffers::iterator qi = _enqueued_index_buffers.find(data);
1118 if (qi != _enqueued_index_buffers.end()) {
1119 _enqueued_index_buffers.erase(qi);
1147 ibc->
get_data()->clear_prepared(
this);
1154 ibc->_object =
nullptr;
1156 bool removed = (_prepared_index_buffers.erase(ibc) != 0);
1159 if (_support_released_buffer_cache) {
1160 cache_unprepared_buffer(ibc, data_size_bytes, usage_hint,
1161 _index_buffer_cache,
1162 _index_buffer_cache_lru, _index_buffer_cache_size,
1163 released_ibuffer_cache_size,
1164 _released_index_buffers);
1166 _released_index_buffers.insert(ibc);
1179 int num_index_buffers = (int)_prepared_index_buffers.size() + (int)_enqueued_index_buffers.size();
1181 Buffers::iterator ibci;
1182 for (ibci = _prepared_index_buffers.begin();
1183 ibci != _prepared_index_buffers.end();
1186 ibc->
get_data()->clear_prepared(
this);
1187 ibc->_object =
nullptr;
1189 _released_index_buffers.insert(ibc);
1192 _prepared_index_buffers.clear();
1193 _enqueued_index_buffers.clear();
1196 BufferCache::iterator bci;
1197 for (bci = _index_buffer_cache.begin();
1198 bci != _index_buffer_cache.end();
1201 nassertr(!buffer_list.empty(), num_index_buffers);
1202 BufferList::iterator li;
1203 for (li = buffer_list.begin(); li != buffer_list.end(); ++li) {
1205 _released_index_buffers.insert(vbc);
1208 _index_buffer_cache.clear();
1209 _index_buffer_cache_lru.clear();
1210 _index_buffer_cache_size = 0;
1212 return num_index_buffers;
1221 return _enqueued_index_buffers.size();
1230 return _prepared_index_buffers.size();
1254 size_t data_size_bytes = data->get_data_size_bytes();
1255 GeomEnums::UsageHint usage_hint = data->get_usage_hint();
1257 get_cached_buffer(data_size_bytes, usage_hint,
1258 _index_buffer_cache, _index_buffer_cache_lru,
1259 _index_buffer_cache_size);
1260 if (ibc !=
nullptr) {
1261 ibc->_object = data;
1267 ibc = gsg->prepare_index_buffer(data);
1270 if (ibc !=
nullptr) {
1271 bool prepared = _prepared_index_buffers.insert(ibc).second;
1272 nassertr(prepared, ibc);
1286 _enqueued_shader_buffers.insert(data);
1297 EnqueuedShaderBuffers::const_iterator qi = _enqueued_shader_buffers.find((
ShaderBuffer *)data);
1298 return (qi != _enqueued_shader_buffers.end());
1314 EnqueuedShaderBuffers::iterator qi = _enqueued_shader_buffers.find(data);
1315 if (qi != _enqueued_shader_buffers.end()) {
1316 _enqueued_shader_buffers.erase(qi);
1345 buffer->clear_prepared(
this);
1349 bc->_object =
nullptr;
1351 bool removed = (_prepared_shader_buffers.erase(bc) != 0);
1354 _released_shader_buffers.insert(bc);
1366 int num_shader_buffers = (int)_prepared_shader_buffers.size() + (int)_enqueued_shader_buffers.size();
1368 Buffers::iterator bci;
1369 for (bci = _prepared_shader_buffers.begin();
1370 bci != _prepared_shader_buffers.end();
1375 bc->_object =
nullptr;
1376 _released_shader_buffers.insert(bc);
1379 _prepared_shader_buffers.clear();
1380 _enqueued_shader_buffers.clear();
1382 return num_shader_buffers;
1391 return _enqueued_shader_buffers.size();
1400 return _prepared_shader_buffers.size();
1428 if (bc !=
nullptr) {
1429 bool prepared = _prepared_shader_buffers.insert(bc).second;
1430 nassertr(prepared, bc);
1472 if (_object ==
nullptr || pgo ==
nullptr) {
1473 nassertr(done(),
false);
1482 if (_object->is_of_type(Texture::get_class_type())) {
1485 }
else if (_object->is_of_type(Geom::get_class_type())) {
1488 }
else if (_object->is_of_type(Shader::get_class_type())) {
1491 }
else if (_object->is_of_type(GeomVertexArrayData::get_class_type())) {
1494 }
else if (_object->is_of_type(GeomPrimitive::get_class_type())) {
1497 }
else if (_object->is_of_type(ShaderBuffer::get_class_type())) {
1516 if (!_released_textures.empty()) {
1517 Textures::iterator tci;
1518 for (tci = _released_textures.begin();
1519 tci != _released_textures.end();
1522 gsg->release_texture(tc);
1525 _released_textures.clear();
1528 if (!_released_samplers.empty()) {
1529 ReleasedSamplers::iterator sci;
1530 for (sci = _released_samplers.begin();
1531 sci != _released_samplers.end();
1534 gsg->release_sampler(sc);
1537 _released_samplers.clear();
1540 Geoms::iterator gci;
1541 for (gci = _released_geoms.begin();
1542 gci != _released_geoms.end();
1545 gsg->release_geom(gc);
1548 _released_geoms.clear();
1550 Shaders::iterator sci;
1551 for (sci = _released_shaders.begin();
1552 sci != _released_shaders.end();
1555 gsg->release_shader(sc);
1558 _released_shaders.clear();
1560 Buffers::iterator vbci;
1561 for (vbci = _released_vertex_buffers.begin();
1562 vbci != _released_vertex_buffers.end();
1565 gsg->release_vertex_buffer(vbc);
1568 _released_vertex_buffers.clear();
1570 Buffers::iterator ibci;
1571 for (ibci = _released_index_buffers.begin();
1572 ibci != _released_index_buffers.end();
1575 gsg->release_index_buffer(ibc);
1578 _released_index_buffers.clear();
1587 EnqueuedTextures::iterator qti;
1588 for (qti = _enqueued_textures.begin();
1589 qti != _enqueued_textures.end();
1594 if (tc !=
nullptr) {
1595 gsg->update_texture(tc,
true);
1596 if (view == 0 && qti->second !=
nullptr) {
1597 qti->second->set_result(tc);
1603 _enqueued_textures.clear();
1605 EnqueuedSamplers::iterator qsmi;
1606 for (qsmi = _enqueued_samplers.begin();
1607 qsmi != _enqueued_samplers.end();
1613 _enqueued_samplers.clear();
1615 EnqueuedGeoms::iterator qgi;
1616 for (qgi = _enqueued_geoms.begin();
1617 qgi != _enqueued_geoms.end();
1619 Geom *geom = (*qgi);
1623 _enqueued_geoms.clear();
1625 EnqueuedShaders::iterator qsi;
1626 for (qsi = _enqueued_shaders.begin();
1627 qsi != _enqueued_shaders.end();
1629 Shader *shader = qsi->first;
1631 if (qsi->second !=
nullptr) {
1632 qsi->second->set_result(sc);
1636 _enqueued_shaders.clear();
1638 EnqueuedVertexBuffers::iterator qvbi;
1639 for (qvbi = _enqueued_vertex_buffers.begin();
1640 qvbi != _enqueued_vertex_buffers.end();
1643 data->prepare_now(
this, gsg);
1646 _enqueued_vertex_buffers.clear();
1648 EnqueuedIndexBuffers::iterator qibi;
1649 for (qibi = _enqueued_index_buffers.begin();
1650 qibi != _enqueued_index_buffers.end();
1655 if (data->is_indexed()) {
1656 data->prepare_now(
this, gsg);
1660 _enqueued_index_buffers.clear();
1671 _texture_residency.
end_frame(current_thread);
1672 _vbuffer_residency.
end_frame(current_thread);
1673 _ibuffer_residency.
end_frame(current_thread);
1674 _sbuffer_residency.
end_frame(current_thread);
1680 std::string PreparedGraphicsObjects::
1683 std::ostringstream strm;
1684 strm <<
"context" << _name_index;
1695 void PreparedGraphicsObjects::
1696 cache_unprepared_buffer(
BufferContext *buffer,
size_t data_size_bytes,
1697 GeomEnums::UsageHint usage_hint,
1700 size_t &buffer_cache_size,
1701 int released_buffer_cache_size,
1702 PreparedGraphicsObjects::Buffers &released_buffers) {
1704 key._data_size_bytes = data_size_bytes;
1705 key._usage_hint = usage_hint;
1707 buffer_cache[key].push_back(buffer);
1708 buffer_cache_size += data_size_bytes;
1711 BufferCacheLRU::iterator li =
1712 find(buffer_cache_lru.begin(), buffer_cache_lru.end(), key);
1713 if (li != buffer_cache_lru.end()) {
1714 buffer_cache_lru.erase(li);
1716 buffer_cache_lru.insert(buffer_cache_lru.begin(), key);
1720 while ((
int)buffer_cache_size > released_buffer_cache_size) {
1721 nassertv(!buffer_cache_lru.empty());
1722 const BufferCacheKey &release_key = *buffer_cache_lru.rbegin();
1723 BufferList &buffer_list = buffer_cache[release_key];
1724 while (!buffer_list.empty() &&
1725 (
int)buffer_cache_size > released_buffer_cache_size) {
1727 buffer_list.pop_back();
1728 released_buffers.insert(released_buffer);
1729 buffer_cache_size -= release_key._data_size_bytes;
1732 if (buffer_list.empty()) {
1733 buffer_cache.erase(release_key);
1734 buffer_cache_lru.pop_back();
1744 get_cached_buffer(
size_t data_size_bytes, GeomEnums::UsageHint usage_hint,
1747 size_t &buffer_cache_size) {
1749 key._data_size_bytes = data_size_bytes;
1750 key._usage_hint = usage_hint;
1752 BufferCache::iterator bci = buffer_cache.find(key);
1753 if (bci == buffer_cache.end()) {
1757 BufferList &buffer_list = (*bci).second;
1758 nassertr(!buffer_list.empty(),
nullptr);
1761 buffer_list.pop_back();
1762 if (buffer_list.empty()) {
1763 buffer_cache.erase(bci);
1764 BufferCacheLRU::iterator li =
1765 find(buffer_cache_lru.begin(), buffer_cache_lru.end(), key);
1766 if (li != buffer_cache_lru.end()) {
1767 buffer_cache_lru.erase(li);
1771 buffer_cache_size -= data_size_bytes;