Panda3D

preparedGraphicsObjects.cxx
Go to the documentation of this file.
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 preparedGraphicsObjects.cxx
10 * @author drose
11 * @date 2004-02-19
12 */
13
14 #include "preparedGraphicsObjects.h"
15 #include "textureContext.h"
16 #include "vertexBufferContext.h"
17 #include "indexBufferContext.h"
18 #include "texture.h"
19 #include "geom.h"
20 #include "geomVertexArrayData.h"
21 #include "geomPrimitive.h"
22 #include "samplerContext.h"
23 #include "shader.h"
24 #include "reMutexHolder.h"
25 #include "geomContext.h"
26 #include "shaderContext.h"
27 #include "config_gobj.h"
28 #include "throw_event.h"
29
30 TypeHandle PreparedGraphicsObjects::EnqueuedObject::_type_handle;
31
32 int PreparedGraphicsObjects::_name_index = 0;
33
34 /**
35 *
36 */
37 PreparedGraphicsObjects::
38 PreparedGraphicsObjects() :
39 _lock("PreparedGraphicsObjects::_lock"),
40 _name(init_name()),
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)
49 {
50 // GLGSG will turn this flag on. This is a temporary hack to disable this
51 // feature for DX8DX9 for now, until we work out the fine points of updating
52 // the fvf properly.
53 _support_released_buffer_cache = false;
54 }
55
56 /**
57 *
58 */
59 PreparedGraphicsObjects::
60 ~PreparedGraphicsObjects() {
61 // There may be objects that are still prepared when we destruct. If this
62 // is so, then all of the GSG's that own them have already destructed, so we
63 // can assume their resources were internally cleaned up. Besides, we may
64 // not even be allowed to call the GSG release methods since some APIs (eg.
65 // OpenGL) require a context current. So we just call the destructors.
66 ReMutexHolder holder(_lock);
67
68 release_all_textures();
69 Textures::iterator tci;
70 for (tci = _released_textures.begin();
71 tci != _released_textures.end();
72 ++tci) {
73 TextureContext *tc = (*tci);
74 delete tc;
75 }
76 _released_textures.clear();
77
78 release_all_samplers();
79 ReleasedSamplers::iterator ssci;
80 for (ssci = _released_samplers.begin();
81 ssci != _released_samplers.end();
82 ++ssci) {
83 SamplerContext *sc = (*ssci);
84 delete sc;
85 }
86 _released_samplers.clear();
87
88 release_all_geoms();
89 Geoms::iterator gci;
90 for (gci = _released_geoms.begin();
91 gci != _released_geoms.end();
92 ++gci) {
93 GeomContext *gc = (*gci);
94 delete gc;
95 }
96 _released_geoms.clear();
97
98 release_all_shaders();
99 Shaders::iterator sci;
100 for (sci = _released_shaders.begin();
101 sci != _released_shaders.end();
102 ++sci) {
103 ShaderContext *sc = (*sci);
104 delete sc;
105 }
106 _released_shaders.clear();
107
108 release_all_vertex_buffers();
109 Buffers::iterator vbci;
110 for (vbci = _released_vertex_buffers.begin();
111 vbci != _released_vertex_buffers.end();
112 ++vbci) {
113 VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
114 delete vbc;
115 }
116 _released_vertex_buffers.clear();
117
118 release_all_index_buffers();
119 Buffers::iterator ibci;
120 for (ibci = _released_index_buffers.begin();
121 ibci != _released_index_buffers.end();
122 ++ibci) {
123 IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
124 delete ibc;
125 }
126 _released_index_buffers.clear();
127
128 release_all_shader_buffers();
129 Buffers::iterator bci;
130 for (bci = _released_shader_buffers.begin();
131 bci != _released_shader_buffers.end();
132 ++bci) {
133 BufferContext *bc = (BufferContext *)(*bci);
134 delete bc;
135 }
136 _released_shader_buffers.clear();
137 }
138
139 /**
140 * Sets an artificial cap on graphics memory that will be imposed on this GSG.
141 *
142 * This limits the total amount of graphics memory, including texture memory
143 * and vertex buffer memory, that will be consumed by the GSG, regardless of
144 * whether the hardware claims to provide more graphics memory than this. It
145 * is useful to put a ceiling on graphics memory consumed, since some drivers
146 * seem to allow the application to consume more memory than the hardware can
147 * realistically support.
148 */
149 void PreparedGraphicsObjects::
150 set_graphics_memory_limit(size_t limit) {
151 if (limit != _graphics_memory_lru.get_max_size()) {
152 _graphics_memory_lru.set_max_size(limit);
153
154 // We throw an event here so global objects (particularly the
155 // TexMemWatcher) can automatically respond to this change.
156 throw_event("graphics_memory_limit_changed");
157 }
158 }
159
160 /**
161 * Writes to the indicated ostream a report of how the various textures and
162 * vertex buffers are allocated in the LRU.
163 */
164 void PreparedGraphicsObjects::
165 show_graphics_memory_lru(std::ostream &out) const {
166 _graphics_memory_lru.write(out, 0);
167 }
168
169 /**
170 * Writes to the indicated ostream a report of how the various textures and
171 * vertex buffers are allocated in the LRU.
172 */
173 void PreparedGraphicsObjects::
174 show_residency_trackers(std::ostream &out) const {
175 out << "Textures:\n";
176 _texture_residency.write(out, 2);
177
178 out << "\nVertex buffers:\n";
179 _vbuffer_residency.write(out, 2);
180
181 out << "\nIndex buffers:\n";
182 _ibuffer_residency.write(out, 2);
183
184 out << "\nShader buffers:\n";
185 _sbuffer_residency.write(out, 2);
186 }
187
188 /**
189 * Indicates that a texture would like to be put on the list to be prepared
190 * when the GSG is next ready to do this (presumably at the next frame).
191 */
192 void PreparedGraphicsObjects::
193 enqueue_texture(Texture *tex) {
194 ReMutexHolder holder(_lock);
195
196 _enqueued_textures.insert(EnqueuedTextures::value_type(tex, nullptr));
197 }
198
199 /**
200 * Like enqueue_texture, but returns an AsyncFuture that can be used to query
201 * the status of the texture's preparation.
202 */
203 PT(PreparedGraphicsObjects::EnqueuedObject) PreparedGraphicsObjects::
204 enqueue_texture_future(Texture *tex) {
205 ReMutexHolder holder(_lock);
206
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);
211 }
212 PT(EnqueuedObject) fut = result.first->second;
213 nassertr(!fut->cancelled(), fut)
214 return fut;
215 }
216
217 /**
218 * Returns true if the texture has been queued on this GSG, false otherwise.
219 */
220 bool PreparedGraphicsObjects::
221 is_texture_queued(const Texture *tex) const {
222 ReMutexHolder holder(_lock);
223
224 EnqueuedTextures::const_iterator qi = _enqueued_textures.find((Texture *)tex);
225 return (qi != _enqueued_textures.end());
226 }
227
228 /**
229 * Removes a texture from the queued list of textures to be prepared.
230 * Normally it is not necessary to call this, unless you change your mind
231 * about preparing it at the last minute, since the texture will automatically
232 * be dequeued and prepared at the next frame.
233 *
234 * The return value is true if the texture is successfully dequeued, false if
235 * it had not been queued.
236 */
237 bool PreparedGraphicsObjects::
238 dequeue_texture(Texture *tex) {
239 ReMutexHolder holder(_lock);
240
241 EnqueuedTextures::iterator qi = _enqueued_textures.find(tex);
242 if (qi != _enqueued_textures.end()) {
243 if (qi->second != nullptr) {
244 qi->second->notify_removed();
245 }
246 _enqueued_textures.erase(qi);
247 return true;
248 }
249 return false;
250 }
251
252 /**
253 * Returns true if the texture has been prepared on this GSG, false otherwise.
254 */
255 bool PreparedGraphicsObjects::
256 is_texture_prepared(const Texture *tex) const {
257 return tex->is_prepared((PreparedGraphicsObjects *)this);
258 }
259
260 /**
261 * Indicates that a texture context, created by a previous call to
262 * prepare_texture(), is no longer needed. The driver resources will not be
263 * freed until some GSG calls update(), indicating it is at a stage where it
264 * is ready to release textures--this prevents conflicts from threading or
265 * multiple GSG's sharing textures (we have no way of knowing which graphics
266 * context is currently active, or what state it's in, at the time
267 * release_texture is called).
268 */
269 void PreparedGraphicsObjects::
270 release_texture(TextureContext *tc) {
271 ReMutexHolder holder(_lock);
272
273 tc->get_texture()->clear_prepared(tc->get_view(), this);
274
275 // We have to set the Texture pointer to NULL at this point, since the
276 // Texture itself might destruct at any time after it has been released.
277 tc->_object = nullptr;
278
279 bool removed = (_prepared_textures.erase(tc) != 0);
280 nassertv(removed);
281
282 _released_textures.insert(tc);
283 }
284
285 /**
286 * Releases a texture if it has already been prepared, or removes it from the
287 * preparation queue.
288 */
289 void PreparedGraphicsObjects::
290 release_texture(Texture *tex) {
291 tex->release(this);
292 }
293
294 /**
295 * Releases all textures at once. This will force them to be reloaded into
296 * texture memory for all GSG's that share this object. Returns the number of
297 * textures released.
298 */
299 int PreparedGraphicsObjects::
300 release_all_textures() {
301 ReMutexHolder holder(_lock);
302
303 int num_textures = (int)_prepared_textures.size() + (int)_enqueued_textures.size();
304
305 Textures::iterator tci;
306 for (tci = _prepared_textures.begin();
307 tci != _prepared_textures.end();
308 ++tci) {
309 TextureContext *tc = (*tci);
310 tc->get_texture()->clear_prepared(tc->get_view(), this);
311 tc->_object = nullptr;
312
313 _released_textures.insert(tc);
314 }
315
316 _prepared_textures.clear();
317
318 // Mark any futures as cancelled.
319 EnqueuedTextures::iterator qti;
320 for (qti = _enqueued_textures.begin();
321 qti != _enqueued_textures.end();
322 ++qti) {
323 if (qti->second != nullptr) {
324 qti->second->notify_removed();
325 }
326 }
327
328 _enqueued_textures.clear();
329
330 return num_textures;
331 }
332
333 /**
334 * Returns the number of textures that have been enqueued to be prepared on
335 * this GSG.
336 */
337 int PreparedGraphicsObjects::
338 get_num_queued_textures() const {
339 return _enqueued_textures.size();
340 }
341
342 /**
343 * Returns the number of textures that have already been prepared on this GSG.
344 */
345 int PreparedGraphicsObjects::
346 get_num_prepared_textures() const {
347 return _prepared_textures.size();
348 }
349
350 /**
351 * Immediately creates a new TextureContext for the indicated texture and
352 * returns it. This assumes that the GraphicsStateGuardian is the currently
353 * active rendering context and that it is ready to accept new textures. If
354 * this is not necessarily the case, you should use enqueue_texture() instead.
355 *
356 * Normally, this function is not called directly. Call
357 * Texture::prepare_now() instead.
358 *
359 * The TextureContext contains all of the pertinent information needed by the
360 * GSG to keep track of this one particular texture, and will exist as long as
361 * the texture is ready to be rendered.
362 *
363 * When either the Texture or the PreparedGraphicsObjects object destructs,
364 * the TextureContext will be deleted.
365 */
366 TextureContext *PreparedGraphicsObjects::
367 prepare_texture_now(Texture *tex, int view, GraphicsStateGuardianBase *gsg) {
368 ReMutexHolder holder(_lock);
369
370 // Ask the GSG to create a brand new TextureContext. There might be several
371 // GSG's sharing the same set of textures; if so, it doesn't matter which of
372 // them creates the context (since they're all shared anyway).
373 TextureContext *tc = gsg->prepare_texture(tex, view);
374
375 if (tc != nullptr) {
376 bool prepared = _prepared_textures.insert(tc).second;
377 nassertr(prepared, tc);
378 }
379
380 return tc;
381 }
382
383 /**
384 * Indicates that a sampler would like to be put on the list to be prepared
385 * when the GSG is next ready to do this (presumably at the next frame).
386 */
387 void PreparedGraphicsObjects::
388 enqueue_sampler(const SamplerState &sampler) {
389 ReMutexHolder holder(_lock);
390
391 _enqueued_samplers.insert(sampler);
392 }
393
394 /**
395 * Returns true if the sampler has been queued on this GSG, false otherwise.
396 */
397 bool PreparedGraphicsObjects::
398 is_sampler_queued(const SamplerState &sampler) const {
399 ReMutexHolder holder(_lock);
400
401 EnqueuedSamplers::const_iterator qi = _enqueued_samplers.find(sampler);
402 return (qi != _enqueued_samplers.end());
403 }
404
405 /**
406 * Removes a sampler from the queued list of samplers to be prepared.
407 * Normally it is not necessary to call this, unless you change your mind
408 * about preparing it at the last minute, since the sampler will automatically
409 * be dequeued and prepared at the next frame.
410 *
411 * The return value is true if the sampler is successfully dequeued, false if
412 * it had not been queued.
413 */
414 bool PreparedGraphicsObjects::
415 dequeue_sampler(const SamplerState &sampler) {
416 ReMutexHolder holder(_lock);
417
418 EnqueuedSamplers::iterator qi = _enqueued_samplers.find(sampler);
419 if (qi != _enqueued_samplers.end()) {
420 _enqueued_samplers.erase(qi);
421 return true;
422 }
423 return false;
424 }
425
426 /**
427 * Returns true if the sampler has been prepared on this GSG, false otherwise.
428 */
429 bool PreparedGraphicsObjects::
430 is_sampler_prepared(const SamplerState &sampler) const {
431 ReMutexHolder holder(_lock);
432
433 PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
434 return (it != _prepared_samplers.end());
435 }
436
437 /**
438 * Indicates that a sampler context, created by a previous call to
439 * prepare_sampler(), is no longer needed. The driver resources will not be
440 * freed until some GSG calls update(), indicating it is at a stage where it
441 * is ready to release samplers.
442 */
443 void PreparedGraphicsObjects::
444 release_sampler(SamplerContext *sc) {
445 ReMutexHolder holder(_lock);
446
447 _released_samplers.insert(sc);
448 }
449
450 /**
451 * Releases a sampler if it has already been prepared, or removes it from the
452 * preparation queue.
453 */
454 void PreparedGraphicsObjects::
455 release_sampler(const SamplerState &sampler) {
456 ReMutexHolder holder(_lock);
457
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);
462 }
463
464 _enqueued_samplers.erase(sampler);
465 }
466
467 /**
468 * Releases all samplers at once. This will force them to be reloaded for all
469 * GSG's that share this object. Returns the number of samplers released.
470 */
471 int PreparedGraphicsObjects::
472 release_all_samplers() {
473 ReMutexHolder holder(_lock);
474
475 int num_samplers = (int)_prepared_samplers.size() + (int)_enqueued_samplers.size();
476
477 PreparedSamplers::iterator sci;
478 for (sci = _prepared_samplers.begin();
479 sci != _prepared_samplers.end();
480 ++sci) {
481 _released_samplers.insert(sci->second);
482 }
483
484 _prepared_samplers.clear();
485 _enqueued_samplers.clear();
486
487 return num_samplers;
488 }
489
490 /**
491 * Returns the number of samplers that have been enqueued to be prepared on
492 * this GSG.
493 */
494 int PreparedGraphicsObjects::
495 get_num_queued_samplers() const {
496 return _enqueued_samplers.size();
497 }
498
499 /**
500 * Returns the number of samplers that have already been prepared on this GSG.
501 */
502 int PreparedGraphicsObjects::
503 get_num_prepared_samplers() const {
504 return _prepared_samplers.size();
505 }
506
507 /**
508 * Immediately creates a new SamplerContext for the indicated sampler and
509 * returns it. This assumes that the GraphicsStateGuardian is the currently
510 * active rendering context and that it is ready to accept new samplers. If
511 * this is not necessarily the case, you should use enqueue_sampler() instead.
512 *
513 * Normally, this function is not called directly. Call
514 * Sampler::prepare_now() instead.
515 *
516 * The SamplerContext contains all of the pertinent information needed by the
517 * GSG to keep track of this one particular sampler, and will exist as long as
518 * the sampler is ready to be rendered.
519 *
520 * When either the Sampler or the PreparedGraphicsObjects object destructs,
521 * the SamplerContext will be deleted.
522 */
523 SamplerContext *PreparedGraphicsObjects::
524 prepare_sampler_now(const SamplerState &sampler, GraphicsStateGuardianBase *gsg) {
525 ReMutexHolder holder(_lock);
526
527 PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
528 if (it != _prepared_samplers.end()) {
529 return it->second;
530 }
531
532 // Ask the GSG to create a brand new SamplerContext.
533 SamplerContext *sc = gsg->prepare_sampler(sampler);
534
535 if (sc != nullptr) {
536 _prepared_samplers[sampler] = sc;
537 }
538
539 return sc;
540 }
541
542 /**
543 * Indicates that a geom would like to be put on the list to be prepared when
544 * the GSG is next ready to do this (presumably at the next frame).
545 */
546 void PreparedGraphicsObjects::
547 enqueue_geom(Geom *geom) {
548 ReMutexHolder holder(_lock);
549
550 _enqueued_geoms.insert(geom);
551 }
552
553 /**
554 * Returns true if the geom has been queued on this GSG, false otherwise.
555 */
556 bool PreparedGraphicsObjects::
557 is_geom_queued(const Geom *geom) const {
558 ReMutexHolder holder(_lock);
559
560 EnqueuedGeoms::const_iterator qi = _enqueued_geoms.find((Geom *)geom);
561 return (qi != _enqueued_geoms.end());
562 }
563
564 /**
565 * Removes a geom from the queued list of geoms to be prepared. Normally it
566 * is not necessary to call this, unless you change your mind about preparing
567 * it at the last minute, since the geom will automatically be dequeued and
568 * prepared at the next frame.
569 *
570 * The return value is true if the geom is successfully dequeued, false if it
571 * had not been queued.
572 */
573 bool PreparedGraphicsObjects::
574 dequeue_geom(Geom *geom) {
575 ReMutexHolder holder(_lock);
576
577 EnqueuedGeoms::iterator qi = _enqueued_geoms.find(geom);
578 if (qi != _enqueued_geoms.end()) {
579 _enqueued_geoms.erase(qi);
580 return true;
581 }
582 return false;
583 }
584
585 /**
586 * Returns true if the vertex buffer has been prepared on this GSG, false
587 * otherwise.
588 */
589 bool PreparedGraphicsObjects::
590 is_geom_prepared(const Geom *geom) const {
591 return geom->is_prepared((PreparedGraphicsObjects *)this);
592 }
593
594 /**
595 * Indicates that a geom context, created by a previous call to
596 * prepare_geom(), is no longer needed. The driver resources will not be
597 * freed until some GSG calls update(), indicating it is at a stage where it
598 * is ready to release geoms--this prevents conflicts from threading or
599 * multiple GSG's sharing geoms (we have no way of knowing which graphics
600 * context is currently active, or what state it's in, at the time
601 * release_geom is called).
602 */
603 void PreparedGraphicsObjects::
604 release_geom(GeomContext *gc) {
605 ReMutexHolder holder(_lock);
606
607 gc->_geom->clear_prepared(this);
608
609 // We have to set the Geom pointer to NULL at this point, since the Geom
610 // itself might destruct at any time after it has been released.
611 gc->_geom = nullptr;
612
613 bool removed = (_prepared_geoms.erase(gc) != 0);
614 nassertv(removed);
615
616 _released_geoms.insert(gc);
617 }
618
619 /**
620 * Releases all geoms at once. This will force them to be reloaded into geom
621 * memory for all GSG's that share this object. Returns the number of geoms
622 * released.
623 */
624 int PreparedGraphicsObjects::
625 release_all_geoms() {
626 ReMutexHolder holder(_lock);
627
628 int num_geoms = (int)_prepared_geoms.size() + (int)_enqueued_geoms.size();
629
630 Geoms::iterator gci;
631 for (gci = _prepared_geoms.begin();
632 gci != _prepared_geoms.end();
633 ++gci) {
634 GeomContext *gc = (*gci);
635 gc->_geom->clear_prepared(this);
636 gc->_geom = nullptr;
637
638 _released_geoms.insert(gc);
639 }
640
641 _prepared_geoms.clear();
642 _enqueued_geoms.clear();
643
644 return num_geoms;
645 }
646
647 /**
648 * Returns the number of geoms that have been enqueued to be prepared on this
649 * GSG.
650 */
651 int PreparedGraphicsObjects::
652 get_num_queued_geoms() const {
653 return _enqueued_geoms.size();
654 }
655
656 /**
657 * Returns the number of geoms that have already been prepared on this GSG.
658 */
659 int PreparedGraphicsObjects::
660 get_num_prepared_geoms() const {
661 return _prepared_geoms.size();
662 }
663
664 /**
665 * Immediately creates a new GeomContext for the indicated geom and returns
666 * it. This assumes that the GraphicsStateGuardian is the currently active
667 * rendering context and that it is ready to accept new geoms. If this is not
668 * necessarily the case, you should use enqueue_geom() instead.
669 *
670 * Normally, this function is not called directly. Call Geom::prepare_now()
671 * instead.
672 *
673 * The GeomContext contains all of the pertinent information needed by the GSG
674 * to keep track of this one particular geom, and will exist as long as the
675 * geom is ready to be rendered.
676 *
677 * When either the Geom or the PreparedGraphicsObjects object destructs, the
678 * GeomContext will be deleted.
679 */
680 GeomContext *PreparedGraphicsObjects::
681 prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg) {
682 ReMutexHolder holder(_lock);
683
684 // Ask the GSG to create a brand new GeomContext. There might be several
685 // GSG's sharing the same set of geoms; if so, it doesn't matter which of
686 // them creates the context (since they're all shared anyway).
687 GeomContext *gc = gsg->prepare_geom(geom);
688
689 if (gc != nullptr) {
690 bool prepared = _prepared_geoms.insert(gc).second;
691 nassertr(prepared, gc);
692 }
693
694 return gc;
695 }
696
697 /**
698 * Indicates that a shader would like to be put on the list to be prepared
699 * when the GSG is next ready to do this (presumably at the next frame).
700 */
701 void PreparedGraphicsObjects::
702 enqueue_shader(Shader *shader) {
703 ReMutexHolder holder(_lock);
704
705 _enqueued_shaders.insert(EnqueuedShaders::value_type(shader, nullptr));
706 }
707
708 /**
709 * Like enqueue_shader, but returns an AsyncFuture that can be used to query
710 * the status of the shader's preparation.
711 */
712 PT(PreparedGraphicsObjects::EnqueuedObject) PreparedGraphicsObjects::
713 enqueue_shader_future(Shader *shader) {
714 ReMutexHolder holder(_lock);
715
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);
720 }
721 PT(EnqueuedObject) fut = result.first->second;
722 nassertr(!fut->cancelled(), fut)
723 return fut;
724 }
725
726 /**
727 * Returns true if the shader has been queued on this GSG, false otherwise.
728 */
729 bool PreparedGraphicsObjects::
730 is_shader_queued(const Shader *shader) const {
731 ReMutexHolder holder(_lock);
732
733 EnqueuedShaders::const_iterator qi = _enqueued_shaders.find((Shader *)shader);
734 return (qi != _enqueued_shaders.end());
735 }
736
737 /**
738 * Removes a shader from the queued list of shaders to be prepared. Normally
739 * it is not necessary to call this, unless you change your mind about
740 * preparing it at the last minute, since the shader will automatically be
741 * dequeued and prepared at the next frame.
742 *
743 * The return value is true if the shader is successfully dequeued, false if
744 * it had not been queued.
745 */
746 bool PreparedGraphicsObjects::
747 dequeue_shader(Shader *se) {
748 ReMutexHolder holder(_lock);
749
750 EnqueuedShaders::iterator qi = _enqueued_shaders.find(se);
751 if (qi != _enqueued_shaders.end()) {
752 if (qi->second != nullptr) {
753 qi->second->notify_removed();
754 }
755 _enqueued_shaders.erase(qi);
756 return true;
757 }
758 return false;
759 }
760
761 /**
762 * Returns true if the shader has been prepared on this GSG, false otherwise.
763 */
764 bool PreparedGraphicsObjects::
765 is_shader_prepared(const Shader *shader) const {
766 return shader->is_prepared((PreparedGraphicsObjects *)this);
767 }
768
769 /**
770 * Indicates that a shader context, created by a previous call to
771 * prepare_shader(), is no longer needed. The driver resources will not be
772 * freed until some GSG calls update(), indicating it is at a stage where it
773 * is ready to release shaders--this prevents conflicts from threading or
774 * multiple GSG's sharing shaders (we have no way of knowing which graphics
775 * context is currently active, or what state it's in, at the time
776 * release_shader is called).
777 */
778 void PreparedGraphicsObjects::
779 release_shader(ShaderContext *sc) {
780 ReMutexHolder holder(_lock);
781
782 sc->_shader->clear_prepared(this);
783
784 // We have to set the Shader pointer to NULL at this point, since the Shader
785 // itself might destruct at any time after it has been released.
786 sc->_shader = nullptr;
787
788 bool removed = (_prepared_shaders.erase(sc) != 0);
789 nassertv(removed);
790
791 _released_shaders.insert(sc);
792 }
793
794 /**
795 * Releases all shaders at once. This will force them to be reloaded into
796 * shader memory for all GSG's that share this object. Returns the number of
797 * shaders released.
798 */
799 int PreparedGraphicsObjects::
800 release_all_shaders() {
801 ReMutexHolder holder(_lock);
802
803 int num_shaders = (int)_prepared_shaders.size() + (int)_enqueued_shaders.size();
804
805 Shaders::iterator sci;
806 for (sci = _prepared_shaders.begin();
807 sci != _prepared_shaders.end();
808 ++sci) {
809 ShaderContext *sc = (*sci);
810 sc->_shader->clear_prepared(this);
811 sc->_shader = nullptr;
812
813 _released_shaders.insert(sc);
814 }
815
816 _prepared_shaders.clear();
817
818 // Mark any futures as cancelled.
819 EnqueuedShaders::iterator qsi;
820 for (qsi = _enqueued_shaders.begin();
821 qsi != _enqueued_shaders.end();
822 ++qsi) {
823 if (qsi->second != nullptr) {
824 qsi->second->notify_removed();
825 }
826 }
827
828 _enqueued_shaders.clear();
829
830 return num_shaders;
831 }
832
833 /**
834 * Returns the number of shaders that have been enqueued to be prepared on
835 * this GSG.
836 */
837 int PreparedGraphicsObjects::
838 get_num_queued_shaders() const {
839 return _enqueued_shaders.size();
840 }
841
842 /**
843 * Returns the number of shaders that have already been prepared on this GSG.
844 */
845 int PreparedGraphicsObjects::
846 get_num_prepared_shaders() const {
847 return _prepared_shaders.size();
848 }
849
850 /**
851 * Immediately creates a new ShaderContext for the indicated shader and
852 * returns it. This assumes that the GraphicsStateGuardian is the currently
853 * active rendering context and that it is ready to accept new shaders. If
854 * this is not necessarily the case, you should use enqueue_shader() instead.
855 *
856 * Normally, this function is not called directly. Call Shader::prepare_now()
857 * instead.
858 *
859 * The ShaderContext contains all of the pertinent information needed by the
860 * GSG to keep track of this one particular shader, and will exist as long as
861 * the shader is ready to be rendered.
862 *
863 * When either the Shader or the PreparedGraphicsObjects object destructs, the
864 * ShaderContext will be deleted.
865 */
866 ShaderContext *PreparedGraphicsObjects::
867 prepare_shader_now(Shader *se, GraphicsStateGuardianBase *gsg) {
868 ReMutexHolder holder(_lock);
869
870 // Ask the GSG to create a brand new ShaderContext. There might be several
871 // GSG's sharing the same set of shaders; if so, it doesn't matter which of
872 // them creates the context (since they're all shared anyway).
873 ShaderContext *sc = gsg->prepare_shader(se);
874
875 if (sc != nullptr) {
876 bool prepared = _prepared_shaders.insert(sc).second;
877 nassertr(prepared, sc);
878 }
879
880 return sc;
881 }
882
883 /**
884 * Indicates that a buffer would like to be put on the list to be prepared
885 * when the GSG is next ready to do this (presumably at the next frame).
886 */
887 void PreparedGraphicsObjects::
888 enqueue_vertex_buffer(GeomVertexArrayData *data) {
889 ReMutexHolder holder(_lock);
890
891 _enqueued_vertex_buffers.insert(data);
892 }
893
894 /**
895 * Returns true if the vertex buffer has been queued on this GSG, false
896 * otherwise.
897 */
898 bool PreparedGraphicsObjects::
899 is_vertex_buffer_queued(const GeomVertexArrayData *data) const {
900 ReMutexHolder holder(_lock);
901
902 EnqueuedVertexBuffers::const_iterator qi = _enqueued_vertex_buffers.find((GeomVertexArrayData *)data);
903 return (qi != _enqueued_vertex_buffers.end());
904 }
905
906 /**
907 * Removes a buffer from the queued list of data arrays to be prepared.
908 * Normally it is not necessary to call this, unless you change your mind
909 * about preparing it at the last minute, since the data will automatically be
910 * dequeued and prepared at the next frame.
911 *
912 * The return value is true if the buffer is successfully dequeued, false if
913 * it had not been queued.
914 */
915 bool PreparedGraphicsObjects::
916 dequeue_vertex_buffer(GeomVertexArrayData *data) {
917 ReMutexHolder holder(_lock);
918
919 EnqueuedVertexBuffers::iterator qi = _enqueued_vertex_buffers.find(data);
920 if (qi != _enqueued_vertex_buffers.end()) {
921 _enqueued_vertex_buffers.erase(qi);
922 return true;
923 }
924 return false;
925 }
926
927 /**
928 * Returns true if the vertex buffer has been prepared on this GSG, false
929 * otherwise.
930 */
931 bool PreparedGraphicsObjects::
932 is_vertex_buffer_prepared(const GeomVertexArrayData *data) const {
933 return data->is_prepared((PreparedGraphicsObjects *)this);
934 }
935
936 /**
937 * Indicates that a data context, created by a previous call to
938 * prepare_vertex_buffer(), is no longer needed. The driver resources will
939 * not be freed until some GSG calls update(), indicating it is at a stage
940 * where it is ready to release datas--this prevents conflicts from threading
941 * or multiple GSG's sharing datas (we have no way of knowing which graphics
942 * context is currently active, or what state it's in, at the time
943 * release_vertex_buffer is called).
944 */
945 void PreparedGraphicsObjects::
946 release_vertex_buffer(VertexBufferContext *vbc) {
947 ReMutexHolder holder(_lock);
948
949 vbc->get_data()->clear_prepared(this);
950
951 size_t data_size_bytes = vbc->get_data()->get_data_size_bytes();
952 GeomEnums::UsageHint usage_hint = vbc->get_data()->get_usage_hint();
953
954 // We have to set the Data pointer to NULL at this point, since the Data
955 // itself might destruct at any time after it has been released.
956 vbc->_object = nullptr;
957
958 bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
959 nassertv(removed);
960
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);
967 } else {
968 _released_vertex_buffers.insert(vbc);
969 }
970 }
971
972 /**
973 * Releases all datas at once. This will force them to be reloaded into data
974 * memory for all GSG's that share this object. Returns the number of datas
975 * released.
976 */
977 int PreparedGraphicsObjects::
978 release_all_vertex_buffers() {
979 ReMutexHolder holder(_lock);
980
981 int num_vertex_buffers = (int)_prepared_vertex_buffers.size() + (int)_enqueued_vertex_buffers.size();
982
983 Buffers::iterator vbci;
984 for (vbci = _prepared_vertex_buffers.begin();
985 vbci != _prepared_vertex_buffers.end();
986 ++vbci) {
987 VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
988 vbc->get_data()->clear_prepared(this);
989 vbc->_object = nullptr;
990
991 _released_vertex_buffers.insert(vbc);
992 }
993
994 _prepared_vertex_buffers.clear();
995 _enqueued_vertex_buffers.clear();
996
997 // Also clear the cache of recently-unprepared vertex buffers.
998 BufferCache::iterator bci;
999 for (bci = _vertex_buffer_cache.begin();
1000 bci != _vertex_buffer_cache.end();
1001 ++bci) {
1002 BufferList &buffer_list = (*bci).second;
1003 nassertr(!buffer_list.empty(), num_vertex_buffers);
1004 BufferList::iterator li;
1005 for (li = buffer_list.begin(); li != buffer_list.end(); ++li) {
1006 VertexBufferContext *vbc = (VertexBufferContext *)(*li);
1007 _released_vertex_buffers.insert(vbc);
1008 }
1009 }
1010 _vertex_buffer_cache.clear();
1011 _vertex_buffer_cache_lru.clear();
1012 _vertex_buffer_cache_size = 0;
1013
1014 return num_vertex_buffers;
1015 }
1016
1017 /**
1018 * Returns the number of vertex buffers that have been enqueued to be prepared
1019 * on this GSG.
1020 */
1021 int PreparedGraphicsObjects::
1022 get_num_queued_vertex_buffers() const {
1023 return _enqueued_vertex_buffers.size();
1024 }
1025
1026 /**
1027 * Returns the number of vertex buffers that have already been prepared on
1028 * this GSG.
1029 */
1030 int PreparedGraphicsObjects::
1031 get_num_prepared_vertex_buffers() const {
1032 return _prepared_vertex_buffers.size();
1033 }
1034
1035 /**
1036 * Immediately creates a new VertexBufferContext for the indicated data and
1037 * returns it. This assumes that the GraphicsStateGuardian is the currently
1038 * active rendering context and that it is ready to accept new datas. If this
1039 * is not necessarily the case, you should use enqueue_vertex_buffer()
1040 * instead.
1041 *
1042 * Normally, this function is not called directly. Call Data::prepare_now()
1043 * instead.
1044 *
1045 * The VertexBufferContext contains all of the pertinent information needed by
1046 * the GSG to keep track of this one particular data, and will exist as long
1047 * as the data is ready to be rendered.
1048 *
1049 * When either the Data or the PreparedGraphicsObjects object destructs, the
1050 * VertexBufferContext will be deleted.
1051 */
1052 VertexBufferContext *PreparedGraphicsObjects::
1053 prepare_vertex_buffer_now(GeomVertexArrayData *data, GraphicsStateGuardianBase *gsg) {
1054 ReMutexHolder holder(_lock);
1055
1056 // First, see if there might be a cached context of the appropriate size.
1057 size_t data_size_bytes = data->get_data_size_bytes();
1058 GeomEnums::UsageHint usage_hint = data->get_usage_hint();
1059 VertexBufferContext *vbc = (VertexBufferContext *)
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;
1065
1066 } else {
1067 // Ask the GSG to create a brand new VertexBufferContext. There might be
1068 // several GSG's sharing the same set of datas; if so, it doesn't matter
1069 // which of them creates the context (since they're all shared anyway).
1070 vbc = gsg->prepare_vertex_buffer(data);
1071 }
1072
1073 if (vbc != nullptr) {
1074 bool prepared = _prepared_vertex_buffers.insert(vbc).second;
1075 nassertr(prepared, vbc);
1076 }
1077
1078 return vbc;
1079 }
1080
1081 /**
1082 * Indicates that a buffer would like to be put on the list to be prepared
1083 * when the GSG is next ready to do this (presumably at the next frame).
1084 */
1085 void PreparedGraphicsObjects::
1086 enqueue_index_buffer(GeomPrimitive *data) {
1087 ReMutexHolder holder(_lock);
1088
1089 _enqueued_index_buffers.insert(data);
1090 }
1091
1092 /**
1093 * Returns true if the index buffer has been queued on this GSG, false
1094 * otherwise.
1095 */
1096 bool PreparedGraphicsObjects::
1097 is_index_buffer_queued(const GeomPrimitive *data) const {
1098 ReMutexHolder holder(_lock);
1099
1100 EnqueuedIndexBuffers::const_iterator qi = _enqueued_index_buffers.find((GeomPrimitive *)data);
1101 return (qi != _enqueued_index_buffers.end());
1102 }
1103
1104 /**
1105 * Removes a buffer from the queued list of data arrays to be prepared.
1106 * Normally it is not necessary to call this, unless you change your mind
1107 * about preparing it at the last minute, since the data will automatically be
1108 * dequeued and prepared at the next frame.
1109 *
1110 * The return value is true if the buffer is successfully dequeued, false if
1111 * it had not been queued.
1112 */
1113 bool PreparedGraphicsObjects::
1114 dequeue_index_buffer(GeomPrimitive *data) {
1115 ReMutexHolder holder(_lock);
1116
1117 EnqueuedIndexBuffers::iterator qi = _enqueued_index_buffers.find(data);
1118 if (qi != _enqueued_index_buffers.end()) {
1119 _enqueued_index_buffers.erase(qi);
1120 return true;
1121 }
1122 return false;
1123 }
1124
1125 /**
1126 * Returns true if the index buffer has been prepared on this GSG, false
1127 * otherwise.
1128 */
1129 bool PreparedGraphicsObjects::
1130 is_index_buffer_prepared(const GeomPrimitive *data) const {
1131 return data->is_prepared((PreparedGraphicsObjects *)this);
1132 }
1133
1134 /**
1135 * Indicates that a data context, created by a previous call to
1136 * prepare_index_buffer(), is no longer needed. The driver resources will not
1137 * be freed until some GSG calls update(), indicating it is at a stage where
1138 * it is ready to release datas--this prevents conflicts from threading or
1139 * multiple GSG's sharing datas (we have no way of knowing which graphics
1140 * context is currently active, or what state it's in, at the time
1141 * release_index_buffer is called).
1142 */
1143 void PreparedGraphicsObjects::
1144 release_index_buffer(IndexBufferContext *ibc) {
1145 ReMutexHolder holder(_lock);
1146
1147 ibc->get_data()->clear_prepared(this);
1148
1149 size_t data_size_bytes = ibc->get_data()->get_data_size_bytes();
1150 GeomEnums::UsageHint usage_hint = ibc->get_data()->get_usage_hint();
1151
1152 // We have to set the Data pointer to NULL at this point, since the Data
1153 // itself might destruct at any time after it has been released.
1154 ibc->_object = nullptr;
1155
1156 bool removed = (_prepared_index_buffers.erase(ibc) != 0);
1157 nassertv(removed);
1158
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);
1165 } else {
1166 _released_index_buffers.insert(ibc);
1167 }
1168 }
1169
1170 /**
1171 * Releases all datas at once. This will force them to be reloaded into data
1172 * memory for all GSG's that share this object. Returns the number of datas
1173 * released.
1174 */
1175 int PreparedGraphicsObjects::
1176 release_all_index_buffers() {
1177 ReMutexHolder holder(_lock);
1178
1179 int num_index_buffers = (int)_prepared_index_buffers.size() + (int)_enqueued_index_buffers.size();
1180
1181 Buffers::iterator ibci;
1182 for (ibci = _prepared_index_buffers.begin();
1183 ibci != _prepared_index_buffers.end();
1184 ++ibci) {
1185 IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
1186 ibc->get_data()->clear_prepared(this);
1187 ibc->_object = nullptr;
1188
1189 _released_index_buffers.insert(ibc);
1190 }
1191
1192 _prepared_index_buffers.clear();
1193 _enqueued_index_buffers.clear();
1194
1195 // Also clear the cache of recently-unprepared index buffers.
1196 BufferCache::iterator bci;
1197 for (bci = _index_buffer_cache.begin();
1198 bci != _index_buffer_cache.end();
1199 ++bci) {
1200 BufferList &buffer_list = (*bci).second;
1201 nassertr(!buffer_list.empty(), num_index_buffers);
1202 BufferList::iterator li;
1203 for (li = buffer_list.begin(); li != buffer_list.end(); ++li) {
1204 IndexBufferContext *vbc = (IndexBufferContext *)(*li);
1205 _released_index_buffers.insert(vbc);
1206 }
1207 }
1208 _index_buffer_cache.clear();
1209 _index_buffer_cache_lru.clear();
1210 _index_buffer_cache_size = 0;
1211
1212 return num_index_buffers;
1213 }
1214
1215 /**
1216 * Returns the number of index buffers that have been enqueued to be prepared
1217 * on this GSG.
1218 */
1219 int PreparedGraphicsObjects::
1220 get_num_queued_index_buffers() const {
1221 return _enqueued_index_buffers.size();
1222 }
1223
1224 /**
1225 * Returns the number of index buffers that have already been prepared on this
1226 * GSG.
1227 */
1228 int PreparedGraphicsObjects::
1229 get_num_prepared_index_buffers() const {
1230 return _prepared_index_buffers.size();
1231 }
1232
1233 /**
1234 * Immediately creates a new IndexBufferContext for the indicated data and
1235 * returns it. This assumes that the GraphicsStateGuardian is the currently
1236 * active rendering context and that it is ready to accept new datas. If this
1237 * is not necessarily the case, you should use enqueue_index_buffer() instead.
1238 *
1239 * Normally, this function is not called directly. Call Data::prepare_now()
1240 * instead.
1241 *
1242 * The IndexBufferContext contains all of the pertinent information needed by
1243 * the GSG to keep track of this one particular data, and will exist as long
1244 * as the data is ready to be rendered.
1245 *
1246 * When either the Data or the PreparedGraphicsObjects object destructs, the
1247 * IndexBufferContext will be deleted.
1248 */
1249 IndexBufferContext *PreparedGraphicsObjects::
1250 prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
1251 ReMutexHolder holder(_lock);
1252
1253 // First, see if there might be a cached context of the appropriate size.
1254 size_t data_size_bytes = data->get_data_size_bytes();
1255 GeomEnums::UsageHint usage_hint = data->get_usage_hint();
1256 IndexBufferContext *ibc = (IndexBufferContext *)
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;
1262
1263 } else {
1264 // Ask the GSG to create a brand new IndexBufferContext. There might be
1265 // several GSG's sharing the same set of datas; if so, it doesn't matter
1266 // which of them creates the context (since they're all shared anyway).
1267 ibc = gsg->prepare_index_buffer(data);
1268 }
1269
1270 if (ibc != nullptr) {
1271 bool prepared = _prepared_index_buffers.insert(ibc).second;
1272 nassertr(prepared, ibc);
1273 }
1274
1275 return ibc;
1276 }
1277
1278 /**
1279 * Indicates that a buffer would like to be put on the list to be prepared
1280 * when the GSG is next ready to do this (presumably at the next frame).
1281 */
1282 void PreparedGraphicsObjects::
1283 enqueue_shader_buffer(ShaderBuffer *data) {
1284 ReMutexHolder holder(_lock);
1285
1286 _enqueued_shader_buffers.insert(data);
1287 }
1288
1289 /**
1290 * Returns true if the index buffer has been queued on this GSG, false
1291 * otherwise.
1292 */
1293 bool PreparedGraphicsObjects::
1294 is_shader_buffer_queued(const ShaderBuffer *data) const {
1295 ReMutexHolder holder(_lock);
1296
1297 EnqueuedShaderBuffers::const_iterator qi = _enqueued_shader_buffers.find((ShaderBuffer *)data);
1298 return (qi != _enqueued_shader_buffers.end());
1299 }
1300
1301 /**
1302 * Removes a buffer from the queued list of data arrays to be prepared.
1303 * Normally it is not necessary to call this, unless you change your mind
1304 * about preparing it at the last minute, since the data will automatically be
1305 * dequeued and prepared at the next frame.
1306 *
1307 * The return value is true if the buffer is successfully dequeued, false if
1308 * it had not been queued.
1309 */
1310 bool PreparedGraphicsObjects::
1311 dequeue_shader_buffer(ShaderBuffer *data) {
1312 ReMutexHolder holder(_lock);
1313
1314 EnqueuedShaderBuffers::iterator qi = _enqueued_shader_buffers.find(data);
1315 if (qi != _enqueued_shader_buffers.end()) {
1316 _enqueued_shader_buffers.erase(qi);
1317 return true;
1318 }
1319 return false;
1320 }
1321
1322 /**
1323 * Returns true if the index buffer has been prepared on this GSG, false
1324 * otherwise.
1325 */
1326 bool PreparedGraphicsObjects::
1327 is_shader_buffer_prepared(const ShaderBuffer *data) const {
1328 return data->is_prepared((PreparedGraphicsObjects *)this);
1329 }
1330
1331 /**
1332 * Indicates that a data context, created by a previous call to
1333 * prepare_shader_buffer(), is no longer needed. The driver resources will not
1334 * be freed until some GSG calls update(), indicating it is at a stage where
1335 * it is ready to release datas--this prevents conflicts from threading or
1336 * multiple GSG's sharing datas (we have no way of knowing which graphics
1337 * context is currently active, or what state it's in, at the time
1338 * release_shader_buffer is called).
1339 */
1340 void PreparedGraphicsObjects::
1341 release_shader_buffer(BufferContext *bc) {
1342 ReMutexHolder holder(_lock);
1343
1344 ShaderBuffer *buffer = (ShaderBuffer *)bc->_object;
1345 buffer->clear_prepared(this);
1346
1347 // We have to set the ShaderBuffer pointer to NULL at this point, since the
1348 // buffer itself might destruct at any time after it has been released.
1349 bc->_object = nullptr;
1350
1351 bool removed = (_prepared_shader_buffers.erase(bc) != 0);
1352 nassertv(removed);
1353
1354 _released_shader_buffers.insert(bc);
1355 }
1356
1357 /**
1358 * Releases all datas at once. This will force them to be reloaded into data
1359 * memory for all GSG's that share this object. Returns the number of datas
1360 * released.
1361 */
1362 int PreparedGraphicsObjects::
1363 release_all_shader_buffers() {
1364 ReMutexHolder holder(_lock);
1365
1366 int num_shader_buffers = (int)_prepared_shader_buffers.size() + (int)_enqueued_shader_buffers.size();
1367
1368 Buffers::iterator bci;
1369 for (bci = _prepared_shader_buffers.begin();
1370 bci != _prepared_shader_buffers.end();
1371 ++bci) {
1372
1373 BufferContext *bc = (BufferContext *)(*bci);
1374 ((ShaderBuffer *)bc->_object)->clear_prepared(this);
1375 bc->_object = nullptr;
1376 _released_shader_buffers.insert(bc);
1377 }
1378
1379 _prepared_shader_buffers.clear();
1380 _enqueued_shader_buffers.clear();
1381
1382 return num_shader_buffers;
1383 }
1384
1385 /**
1386 * Returns the number of index buffers that have been enqueued to be prepared
1387 * on this GSG.
1388 */
1389 int PreparedGraphicsObjects::
1390 get_num_queued_shader_buffers() const {
1391 return _enqueued_shader_buffers.size();
1392 }
1393
1394 /**
1395 * Returns the number of index buffers that have already been prepared on this
1396 * GSG.
1397 */
1398 int PreparedGraphicsObjects::
1399 get_num_prepared_shader_buffers() const {
1400 return _prepared_shader_buffers.size();
1401 }
1402
1403 /**
1404 * Immediately creates a new BufferContext for the indicated data and
1405 * returns it. This assumes that the GraphicsStateGuardian is the currently
1406 * active rendering context and that it is ready to accept new datas. If this
1407 * is not necessarily the case, you should use enqueue_shader_buffer() instead.
1408 *
1409 * Normally, this function is not called directly. Call Data::prepare_now()
1410 * instead.
1411 *
1412 * The BufferContext contains all of the pertinent information needed by
1413 * the GSG to keep track of this one particular data, and will exist as long
1414 * as the data is ready to be rendered.
1415 *
1416 * When either the Data or the PreparedGraphicsObjects object destructs, the
1417 * BufferContext will be deleted.
1418 */
1419 BufferContext *PreparedGraphicsObjects::
1420 prepare_shader_buffer_now(ShaderBuffer *data, GraphicsStateGuardianBase *gsg) {
1421 ReMutexHolder holder(_lock);
1422
1423 // Ask the GSG to create a brand new BufferContext. There might be
1424 // several GSG's sharing the same set of datas; if so, it doesn't matter
1425 // which of them creates the context (since they're all shared anyway).
1426 BufferContext *bc = gsg->prepare_shader_buffer(data);
1427
1428 if (bc != nullptr) {
1429 bool prepared = _prepared_shader_buffers.insert(bc).second;
1430 nassertr(prepared, bc);
1431 }
1432
1433 return bc;
1434 }
1435
1436 /**
1437 * Creates a new future for the given object.
1438 */
1439 PreparedGraphicsObjects::EnqueuedObject::
1440 EnqueuedObject(PreparedGraphicsObjects *pgo, TypedWritableReferenceCount *object) :
1441 _pgo(pgo),
1442 _object(object) {
1443 }
1444
1445 /**
1446 * Indicates that the preparation request is done.
1447 */
1448 void PreparedGraphicsObjects::EnqueuedObject::
1449 set_result(SavedContext *context) {
1450 nassertv(!done());
1451 AsyncFuture::set_result(context);
1452 _pgo = nullptr;
1453 }
1454
1455 /**
1456 * Called by PreparedGraphicsObjects to indicate that the preparation request
1457 * has been cancelled.
1458 */
1459 void PreparedGraphicsObjects::EnqueuedObject::
1460 notify_removed() {
1461 _pgo = nullptr;
1462 nassertv_always(AsyncFuture::cancel());
1463 }
1464
1465 /**
1466 * Cancels the pending preparation request. Has no effect if the preparation
1467 * is already complete or was already cancelled.
1468 */
1469 bool PreparedGraphicsObjects::EnqueuedObject::
1470 cancel() {
1471 PreparedGraphicsObjects *pgo = _pgo;
1472 if (_object == nullptr || pgo == nullptr) {
1473 nassertr(done(), false);
1474 return false;
1475 }
1476
1477 // We don't upcall here, because the dequeue function will end up calling
1478 // notify_removed().
1479 _result = nullptr;
1480 _pgo = nullptr;
1481
1482 if (_object->is_of_type(Texture::get_class_type())) {
1483 return pgo->dequeue_texture((Texture *)_object.p());
1484
1485 } else if (_object->is_of_type(Geom::get_class_type())) {
1486 return pgo->dequeue_geom((Geom *)_object.p());
1487
1488 } else if (_object->is_of_type(Shader::get_class_type())) {
1489 return pgo->dequeue_shader((Shader *)_object.p());
1490
1491 } else if (_object->is_of_type(GeomVertexArrayData::get_class_type())) {
1492 return pgo->dequeue_vertex_buffer((GeomVertexArrayData *)_object.p());
1493
1494 } else if (_object->is_of_type(GeomPrimitive::get_class_type())) {
1495 return pgo->dequeue_index_buffer((GeomPrimitive *)_object.p());
1496
1497 } else if (_object->is_of_type(ShaderBuffer::get_class_type())) {
1498 return pgo->dequeue_shader_buffer((ShaderBuffer *)_object.p());
1499 }
1500 return false;
1501 }
1502
1503 /**
1504 * This is called by the GraphicsStateGuardian to indicate that it is about to
1505 * begin processing of the frame.
1506 *
1507 * Any texture contexts that were previously passed to release_texture() are
1508 * actually passed to the GSG to be freed at this point; textures that were
1509 * previously passed to prepare_texture are actually loaded.
1510 */
1511 void PreparedGraphicsObjects::
1512 begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
1513 ReMutexHolder holder(_lock, current_thread);
1514
1515 // First, release all the textures, geoms, and buffers awaiting release.
1516 if (!_released_textures.empty()) {
1517 Textures::iterator tci;
1518 for (tci = _released_textures.begin();
1519 tci != _released_textures.end();
1520 ++tci) {
1521 TextureContext *tc = (*tci);
1522 gsg->release_texture(tc);
1523 }
1524
1525 _released_textures.clear();
1526 }
1527
1528 if (!_released_samplers.empty()) {
1529 ReleasedSamplers::iterator sci;
1530 for (sci = _released_samplers.begin();
1531 sci != _released_samplers.end();
1532 ++sci) {
1533 SamplerContext *sc = (*sci);
1534 gsg->release_sampler(sc);
1535 }
1536
1537 _released_samplers.clear();
1538 }
1539
1540 Geoms::iterator gci;
1541 for (gci = _released_geoms.begin();
1542 gci != _released_geoms.end();
1543 ++gci) {
1544 GeomContext *gc = (*gci);
1545 gsg->release_geom(gc);
1546 }
1547
1548 _released_geoms.clear();
1549
1550 Shaders::iterator sci;
1551 for (sci = _released_shaders.begin();
1552 sci != _released_shaders.end();
1553 ++sci) {
1554 ShaderContext *sc = (*sci);
1555 gsg->release_shader(sc);
1556 }
1557
1558 _released_shaders.clear();
1559
1560 Buffers::iterator vbci;
1561 for (vbci = _released_vertex_buffers.begin();
1562 vbci != _released_vertex_buffers.end();
1563 ++vbci) {
1564 VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
1565 gsg->release_vertex_buffer(vbc);
1566 }
1567
1568 _released_vertex_buffers.clear();
1569
1570 Buffers::iterator ibci;
1571 for (ibci = _released_index_buffers.begin();
1572 ibci != _released_index_buffers.end();
1573 ++ibci) {
1574 IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
1575 gsg->release_index_buffer(ibc);
1576 }
1577
1578 _released_index_buffers.clear();
1579
1580 // Reset the residency trackers.
1581 _texture_residency.begin_frame(current_thread);
1582 _vbuffer_residency.begin_frame(current_thread);
1583 _ibuffer_residency.begin_frame(current_thread);
1584 _sbuffer_residency.begin_frame(current_thread);
1585
1586 // Now prepare all the textures, geoms, and buffers awaiting preparation.
1587 EnqueuedTextures::iterator qti;
1588 for (qti = _enqueued_textures.begin();
1589 qti != _enqueued_textures.end();
1590 ++qti) {
1591 Texture *tex = qti->first;
1592 for (int view = 0; view < tex->get_num_views(); ++view) {
1593 TextureContext *tc = tex->prepare_now(view, this, gsg);
1594 if (tc != nullptr) {
1595 gsg->update_texture(tc, true);
1596 if (view == 0 && qti->second != nullptr) {
1597 qti->second->set_result(tc);
1598 }
1599 }
1600 }
1601 }
1602
1603 _enqueued_textures.clear();
1604
1605 EnqueuedSamplers::iterator qsmi;
1606 for (qsmi = _enqueued_samplers.begin();
1607 qsmi != _enqueued_samplers.end();
1608 ++qsmi) {
1609 const SamplerState &sampler = (*qsmi);
1610 sampler.prepare_now(this, gsg);
1611 }
1612
1613 _enqueued_samplers.clear();
1614
1615 EnqueuedGeoms::iterator qgi;
1616 for (qgi = _enqueued_geoms.begin();
1617 qgi != _enqueued_geoms.end();
1618 ++qgi) {
1619 Geom *geom = (*qgi);
1620 geom->prepare_now(this, gsg);
1621 }
1622
1623 _enqueued_geoms.clear();
1624
1625 EnqueuedShaders::iterator qsi;
1626 for (qsi = _enqueued_shaders.begin();
1627 qsi != _enqueued_shaders.end();
1628 ++qsi) {
1629 Shader *shader = qsi->first;
1630 ShaderContext *sc = shader->prepare_now(this, gsg);
1631 if (qsi->second != nullptr) {
1632 qsi->second->set_result(sc);
1633 }
1634 }
1635
1636 _enqueued_shaders.clear();
1637
1638 EnqueuedVertexBuffers::iterator qvbi;
1639 for (qvbi = _enqueued_vertex_buffers.begin();
1640 qvbi != _enqueued_vertex_buffers.end();
1641 ++qvbi) {
1642 GeomVertexArrayData *data = (*qvbi);
1643 data->prepare_now(this, gsg);
1644 }
1645
1646 _enqueued_vertex_buffers.clear();
1647
1648 EnqueuedIndexBuffers::iterator qibi;
1649 for (qibi = _enqueued_index_buffers.begin();
1650 qibi != _enqueued_index_buffers.end();
1651 ++qibi) {
1652 GeomPrimitive *data = (*qibi);
1653 // We need this check because the actual index data may not actually have
1654 // propagated to the draw thread yet.
1655 if (data->is_indexed()) {
1656 data->prepare_now(this, gsg);
1657 }
1658 }
1659
1660 _enqueued_index_buffers.clear();
1661 }
1662
1663 /**
1664 * This is called by the GraphicsStateGuardian to indicate that it has
1665 * finished processing of the frame.
1666 */
1667 void PreparedGraphicsObjects::
1668 end_frame(Thread *current_thread) {
1669 ReMutexHolder holder(_lock, current_thread);
1670
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);
1675 }
1676
1677 /**
1678 * Returns a new, unique name for a newly-constructed object.
1679 */
1680 std::string PreparedGraphicsObjects::
1681 init_name() {
1682 ++_name_index;
1683 std::ostringstream strm;
1684 strm << "context" << _name_index;
1685 return strm.str();
1686 }
1687
1688 /**
1689 * Called when a vertex or index buffer is no longer officially "prepared".
1690 * However, we still have the context on the graphics card, and we might be
1691 * able to reuse that context if we're about to re-prepare a different buffer,
1692 * especially one exactly the same size. So instead of immediately enqueuing
1693 * the vertex buffer for release, we cache it.
1694 */
1695 void PreparedGraphicsObjects::
1696 cache_unprepared_buffer(BufferContext *buffer, size_t data_size_bytes,
1697 GeomEnums::UsageHint usage_hint,
1698 PreparedGraphicsObjects::BufferCache &buffer_cache,
1699 PreparedGraphicsObjects::BufferCacheLRU &buffer_cache_lru,
1700 size_t &buffer_cache_size,
1701 int released_buffer_cache_size,
1702 PreparedGraphicsObjects::Buffers &released_buffers) {
1703 BufferCacheKey key;
1704 key._data_size_bytes = data_size_bytes;
1705 key._usage_hint = usage_hint;
1706
1707 buffer_cache[key].push_back(buffer);
1708 buffer_cache_size += data_size_bytes;
1709
1710 // Move the key to the head of the LRU.
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);
1715 }
1716 buffer_cache_lru.insert(buffer_cache_lru.begin(), key);
1717
1718 // Now release not-recently-used buffers until we fit within the constrained
1719 // size.
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) {
1726 BufferContext *released_buffer = buffer_list.back();
1727 buffer_list.pop_back();
1728 released_buffers.insert(released_buffer);
1729 buffer_cache_size -= release_key._data_size_bytes;
1730 }
1731
1732 if (buffer_list.empty()) {
1733 buffer_cache.erase(release_key);
1734 buffer_cache_lru.pop_back();
1735 }
1736 }
1737 }
1738
1739 /**
1740 * Returns a previously-cached buffer from the cache, or NULL if there is no
1741 * such buffer.
1742 */
1743 BufferContext *PreparedGraphicsObjects::
1744 get_cached_buffer(size_t data_size_bytes, GeomEnums::UsageHint usage_hint,
1745 PreparedGraphicsObjects::BufferCache &buffer_cache,
1746 PreparedGraphicsObjects::BufferCacheLRU &buffer_cache_lru,
1747 size_t &buffer_cache_size) {
1748 BufferCacheKey key;
1749 key._data_size_bytes = data_size_bytes;
1750 key._usage_hint = usage_hint;
1751
1752 BufferCache::iterator bci = buffer_cache.find(key);
1753 if (bci == buffer_cache.end()) {
1754 return nullptr;
1755 }
1756
1757 BufferList &buffer_list = (*bci).second;
1758 nassertr(!buffer_list.empty(), nullptr);
1759
1760 BufferContext *buffer = buffer_list.back();
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);
1768 }
1769 }
1770
1771 buffer_cache_size -= data_size_bytes;
1772 return buffer;
1773 }
AdaptiveLru::set_max_size
void set_max_size(size_t max_size)
Changes the max size of all objects that are allowed to be active on the LRU.
Definition: adaptiveLru.I:40
AdaptiveLru::get_max_size
size_t get_max_size() const
Returns the max size of all objects that are allowed to be active on the LRU.
Definition: adaptiveLru.I:28
AsyncFuture::cancel
virtual bool cancel()
Cancels the future.
Definition: asyncFuture.cxx:57
AsyncFuture::set_result
void set_result(std::nullptr_t)
Sets this future's result.
Definition: asyncFuture.I:92
BufferContext
This is a base class for those kinds of SavedContexts that occupy an easily-measured (and substantial...
Definition: bufferContext.h:38
BufferResidencyTracker::end_frame
void end_frame(Thread *current_thread)
To be called at the end of a frame, this updates the PStatCollectors appropriately.
Definition: bufferResidencyTracker.cxx:70
BufferResidencyTracker::begin_frame
void begin_frame(Thread *current_thread)
To be called at the beginning of a frame, this initializes the active/inactive status.
Definition: bufferResidencyTracker.cxx:51
GeomContext
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: geomContext.h:34
GeomPrimitive
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
GeomPrimitive::get_data_size_bytes
get_data_size_bytes
Returns the number of bytes stored in the vertices array.
Definition: geomPrimitive.h:143
GeomPrimitive::get_usage_hint
get_usage_hint
Returns the usage hint for this primitive.
Definition: geomPrimitive.h:81
GeomVertexArrayData
This is the data for one array of a GeomVertexData structure.
Definition: geomVertexArrayData.h:58
GeomVertexArrayData::get_usage_hint
get_usage_hint
Returns the usage hint that describes to the rendering backend how often the vertex data will be modi...
Definition: geomVertexArrayData.h:80
GeomVertexArrayData::get_data_size_bytes
get_data_size_bytes
Returns the number of bytes stored in the array.
Definition: geomVertexArrayData.h:92
Geom
A container for geometry primitives.
Definition: geom.h:54
Geom::prepare_now
GeomContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the geom on the particular GSG, if it does not already exist.
Definition: geom.cxx:1282
Geom::is_prepared
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const
Returns true if the geom has already been prepared or enqueued for preparation on the indicated GSG,...
Definition: geom.cxx:1216
GraphicsStateGuardianBase
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
Definition: graphicsStateGuardianBase.h:110
IndexBufferContext
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: indexBufferContext.h:33
IndexBufferContext::get_data
GeomPrimitive * get_data() const
Returns the pointer to the client-side array data object.
Definition: indexBufferContext.I:28
PreparedGraphicsObjects::EnqueuedObject
This is a handle to an enqueued object, from which the result can be obtained upon completion.
Definition: preparedGraphicsObjects.h:167
PreparedGraphicsObjects::EnqueuedObject::set_result
void set_result(SavedContext *result)
Indicates that the preparation request is done.
Definition: preparedGraphicsObjects.cxx:1449
PreparedGraphicsObjects::EnqueuedObject::cancel
virtual bool cancel() final
Cancels the pending preparation request.
Definition: preparedGraphicsObjects.cxx:1470
PreparedGraphicsObjects::EnqueuedObject::EnqueuedObject
EnqueuedObject(PreparedGraphicsObjects *pgo, TypedWritableReferenceCount *object)
Creates a new future for the given object.
Definition: preparedGraphicsObjects.cxx:1440
PreparedGraphicsObjects::EnqueuedObject::notify_removed
void notify_removed()
Called by PreparedGraphicsObjects to indicate that the preparation request has been cancelled.
Definition: preparedGraphicsObjects.cxx:1460
PreparedGraphicsObjects
A table of objects that are saved within the graphics context for reference by handle later.
Definition: preparedGraphicsObjects.h:58
PreparedGraphicsObjects::enqueue_vertex_buffer
void enqueue_vertex_buffer(GeomVertexArrayData *data)
Indicates that a buffer would like to be put on the list to be prepared when the GSG is next ready to...
Definition: preparedGraphicsObjects.cxx:888
PreparedGraphicsObjects::get_num_queued_geoms
int get_num_queued_geoms() const
Returns the number of geoms that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:652
PreparedGraphicsObjects::release_all_geoms
int release_all_geoms()
Releases all geoms at once.
Definition: preparedGraphicsObjects.cxx:625
PreparedGraphicsObjects::release_sampler
void release_sampler(SamplerContext *sc)
Indicates that a sampler context, created by a previous call to prepare_sampler(),...
Definition: preparedGraphicsObjects.cxx:444
PreparedGraphicsObjects::dequeue_vertex_buffer
bool dequeue_vertex_buffer(GeomVertexArrayData *data)
Removes a buffer from the queued list of data arrays to be prepared.
Definition: preparedGraphicsObjects.cxx:916
PreparedGraphicsObjects::is_texture_queued
bool is_texture_queued(const Texture *tex) const
Returns true if the texture has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:221
PreparedGraphicsObjects::release_all_textures
int release_all_textures()
Releases all textures at once.
Definition: preparedGraphicsObjects.cxx:300
PreparedGraphicsObjects::get_num_prepared_shaders
int get_num_prepared_shaders() const
Returns the number of shaders that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:846
PreparedGraphicsObjects::get_num_queued_index_buffers
int get_num_queued_index_buffers() const
Returns the number of index buffers that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1220
PreparedGraphicsObjects::get_num_prepared_shader_buffers
int get_num_prepared_shader_buffers() const
Returns the number of index buffers that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1399
PreparedGraphicsObjects::prepare_texture_now
TextureContext * prepare_texture_now(Texture *tex, int view, GraphicsStateGuardianBase *gsg)
Immediately creates a new TextureContext for the indicated texture and returns it.
Definition: preparedGraphicsObjects.cxx:367
PreparedGraphicsObjects::get_num_prepared_vertex_buffers
int get_num_prepared_vertex_buffers() const
Returns the number of vertex buffers that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1031
PreparedGraphicsObjects::release_geom
void release_geom(GeomContext *gc)
Indicates that a geom context, created by a previous call to prepare_geom(), is no longer needed.
Definition: preparedGraphicsObjects.cxx:604
PreparedGraphicsObjects::is_index_buffer_prepared
bool is_index_buffer_prepared(const GeomPrimitive *data) const
Returns true if the index buffer has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:1130
PreparedGraphicsObjects::get_num_prepared_textures
int get_num_prepared_textures() const
Returns the number of textures that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:346
PreparedGraphicsObjects::enqueue_sampler
void enqueue_sampler(const SamplerState &sampler)
Indicates that a sampler would like to be put on the list to be prepared when the GSG is next ready t...
Definition: preparedGraphicsObjects.cxx:388
PreparedGraphicsObjects::enqueue_texture
void enqueue_texture(Texture *tex)
Indicates that a texture would like to be put on the list to be prepared when the GSG is next ready t...
Definition: preparedGraphicsObjects.cxx:193
PreparedGraphicsObjects::get_num_queued_vertex_buffers
int get_num_queued_vertex_buffers() const
Returns the number of vertex buffers that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1022
PreparedGraphicsObjects::show_residency_trackers
void show_residency_trackers(std::ostream &out) const
Writes to the indicated ostream a report of how the various textures and vertex buffers are allocated...
Definition: preparedGraphicsObjects.cxx:174
PreparedGraphicsObjects::is_shader_queued
bool is_shader_queued(const Shader *shader) const
Returns true if the shader has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:730
PreparedGraphicsObjects::prepare_sampler_now
SamplerContext * prepare_sampler_now(const SamplerState &sampler, GraphicsStateGuardianBase *gsg)
Immediately creates a new SamplerContext for the indicated sampler and returns it.
Definition: preparedGraphicsObjects.cxx:524
PreparedGraphicsObjects::is_geom_prepared
bool is_geom_prepared(const Geom *geom) const
Returns true if the vertex buffer has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:590
PreparedGraphicsObjects::get_num_queued_samplers
int get_num_queued_samplers() const
Returns the number of samplers that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:495
PreparedGraphicsObjects::is_shader_buffer_queued
bool is_shader_buffer_queued(const ShaderBuffer *data) const
Returns true if the index buffer has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:1294
PreparedGraphicsObjects::get_num_queued_shaders
int get_num_queued_shaders() const
Returns the number of shaders that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:838
PreparedGraphicsObjects::dequeue_shader
bool dequeue_shader(Shader *shader)
Removes a shader from the queued list of shaders to be prepared.
Definition: preparedGraphicsObjects.cxx:747
PreparedGraphicsObjects::is_texture_prepared
bool is_texture_prepared(const Texture *tex) const
Returns true if the texture has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:256
PreparedGraphicsObjects::release_shader_buffer
void release_shader_buffer(BufferContext *bc)
Indicates that a data context, created by a previous call to prepare_shader_buffer(),...
Definition: preparedGraphicsObjects.cxx:1341
PreparedGraphicsObjects::release_all_shaders
int release_all_shaders()
Releases all shaders at once.
Definition: preparedGraphicsObjects.cxx:800
PreparedGraphicsObjects::is_sampler_prepared
bool is_sampler_prepared(const SamplerState &sampler) const
Returns true if the sampler has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:430
PreparedGraphicsObjects::get_num_queued_textures
int get_num_queued_textures() const
Returns the number of textures that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:338
PreparedGraphicsObjects::is_sampler_queued
bool is_sampler_queued(const SamplerState &sampler) const
Returns true if the sampler has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:398
PreparedGraphicsObjects::dequeue_sampler
bool dequeue_sampler(const SamplerState &sampler)
Removes a sampler from the queued list of samplers to be prepared.
Definition: preparedGraphicsObjects.cxx:415
PreparedGraphicsObjects::release_all_index_buffers
int release_all_index_buffers()
Releases all datas at once.
Definition: preparedGraphicsObjects.cxx:1176
PreparedGraphicsObjects::is_geom_queued
bool is_geom_queued(const Geom *geom) const
Returns true if the geom has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:557
PreparedGraphicsObjects::get_num_prepared_geoms
int get_num_prepared_geoms() const
Returns the number of geoms that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:660
PreparedGraphicsObjects::release_shader
void release_shader(ShaderContext *sc)
Indicates that a shader context, created by a previous call to prepare_shader(), is no longer needed.
Definition: preparedGraphicsObjects.cxx:779
PreparedGraphicsObjects::release_all_shader_buffers
int release_all_shader_buffers()
Releases all datas at once.
Definition: preparedGraphicsObjects.cxx:1363
PreparedGraphicsObjects::is_index_buffer_queued
bool is_index_buffer_queued(const GeomPrimitive *data) const
Returns true if the index buffer has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:1097
PreparedGraphicsObjects::is_shader_buffer_prepared
bool is_shader_buffer_prepared(const ShaderBuffer *data) const
Returns true if the index buffer has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:1327
PreparedGraphicsObjects::set_graphics_memory_limit
void set_graphics_memory_limit(size_t limit)
Sets an artificial cap on graphics memory that will be imposed on this GSG.
Definition: preparedGraphicsObjects.cxx:150
PreparedGraphicsObjects::dequeue_texture
bool dequeue_texture(Texture *tex)
Removes a texture from the queued list of textures to be prepared.
Definition: preparedGraphicsObjects.cxx:238
PreparedGraphicsObjects::prepare_geom_now
GeomContext * prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg)
Immediately creates a new GeomContext for the indicated geom and returns it.
Definition: preparedGraphicsObjects.cxx:681
PreparedGraphicsObjects::end_frame
void end_frame(Thread *current_thread)
This is called by the GraphicsStateGuardian to indicate that it has finished processing of the frame.
Definition: preparedGraphicsObjects.cxx:1668
PreparedGraphicsObjects::release_all_samplers
int release_all_samplers()
Releases all samplers at once.
Definition: preparedGraphicsObjects.cxx:472
PreparedGraphicsObjects::show_graphics_memory_lru
void show_graphics_memory_lru(std::ostream &out) const
Writes to the indicated ostream a report of how the various textures and vertex buffers are allocated...
Definition: preparedGraphicsObjects.cxx:165
PreparedGraphicsObjects::dequeue_shader_buffer
bool dequeue_shader_buffer(ShaderBuffer *data)
Removes a buffer from the queued list of data arrays to be prepared.
Definition: preparedGraphicsObjects.cxx:1311
PreparedGraphicsObjects::dequeue_geom
bool dequeue_geom(Geom *geom)
Removes a geom from the queued list of geoms to be prepared.
Definition: preparedGraphicsObjects.cxx:574
PreparedGraphicsObjects::release_index_buffer
void release_index_buffer(IndexBufferContext *ibc)
Indicates that a data context, created by a previous call to prepare_index_buffer(),...
Definition: preparedGraphicsObjects.cxx:1144
PreparedGraphicsObjects::get_num_prepared_samplers
int get_num_prepared_samplers() const
Returns the number of samplers that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:503
PreparedGraphicsObjects::is_shader_prepared
bool is_shader_prepared(const Shader *shader) const
Returns true if the shader has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:765
PreparedGraphicsObjects::is_vertex_buffer_prepared
bool is_vertex_buffer_prepared(const GeomVertexArrayData *data) const
Returns true if the vertex buffer has been prepared on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:932
PreparedGraphicsObjects::begin_frame
void begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread)
This is called by the GraphicsStateGuardian to indicate that it is about to begin processing of the f...
Definition: preparedGraphicsObjects.cxx:1512
PreparedGraphicsObjects::enqueue_index_buffer
void enqueue_index_buffer(GeomPrimitive *data)
Indicates that a buffer would like to be put on the list to be prepared when the GSG is next ready to...
Definition: preparedGraphicsObjects.cxx:1086
PreparedGraphicsObjects::prepare_shader_buffer_now
BufferContext * prepare_shader_buffer_now(ShaderBuffer *data, GraphicsStateGuardianBase *gsg)
Immediately creates a new BufferContext for the indicated data and returns it.
Definition: preparedGraphicsObjects.cxx:1420
PreparedGraphicsObjects::release_vertex_buffer
void release_vertex_buffer(VertexBufferContext *vbc)
Indicates that a data context, created by a previous call to prepare_vertex_buffer(),...
Definition: preparedGraphicsObjects.cxx:946
PreparedGraphicsObjects::enqueue_shader
void enqueue_shader(Shader *shader)
Indicates that a shader would like to be put on the list to be prepared when the GSG is next ready to...
Definition: preparedGraphicsObjects.cxx:702
PreparedGraphicsObjects::enqueue_geom
void enqueue_geom(Geom *geom)
Indicates that a geom would like to be put on the list to be prepared when the GSG is next ready to d...
Definition: preparedGraphicsObjects.cxx:547
PreparedGraphicsObjects::is_vertex_buffer_queued
bool is_vertex_buffer_queued(const GeomVertexArrayData *data) const
Returns true if the vertex buffer has been queued on this GSG, false otherwise.
Definition: preparedGraphicsObjects.cxx:899
PreparedGraphicsObjects::release_texture
void release_texture(TextureContext *tc)
Indicates that a texture context, created by a previous call to prepare_texture(),...
Definition: preparedGraphicsObjects.cxx:270
PreparedGraphicsObjects::get_num_queued_shader_buffers
int get_num_queued_shader_buffers() const
Returns the number of index buffers that have been enqueued to be prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1390
PreparedGraphicsObjects::release_all_vertex_buffers
int release_all_vertex_buffers()
Releases all datas at once.
Definition: preparedGraphicsObjects.cxx:978
PreparedGraphicsObjects::get_num_prepared_index_buffers
int get_num_prepared_index_buffers() const
Returns the number of index buffers that have already been prepared on this GSG.
Definition: preparedGraphicsObjects.cxx:1229
PreparedGraphicsObjects::prepare_index_buffer_now
IndexBufferContext * prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg)
Immediately creates a new IndexBufferContext for the indicated data and returns it.
Definition: preparedGraphicsObjects.cxx:1250
PreparedGraphicsObjects::prepare_shader_now
ShaderContext * prepare_shader_now(Shader *shader, GraphicsStateGuardianBase *gsg)
Immediately creates a new ShaderContext for the indicated shader and returns it.
Definition: preparedGraphicsObjects.cxx:867
PreparedGraphicsObjects::enqueue_shader_buffer
void enqueue_shader_buffer(ShaderBuffer *data)
Indicates that a buffer would like to be put on the list to be prepared when the GSG is next ready to...
Definition: preparedGraphicsObjects.cxx:1283
PreparedGraphicsObjects::prepare_vertex_buffer_now
VertexBufferContext * prepare_vertex_buffer_now(GeomVertexArrayData *data, GraphicsStateGuardianBase *gsg)
Immediately creates a new VertexBufferContext for the indicated data and returns it.
Definition: preparedGraphicsObjects.cxx:1053
PreparedGraphicsObjects::dequeue_index_buffer
bool dequeue_index_buffer(GeomPrimitive *data)
Removes a buffer from the queued list of data arrays to be prepared.
Definition: preparedGraphicsObjects.cxx:1114
ReMutexHolder
Similar to MutexHolder, but for a reentrant mutex.
Definition: reMutexHolder.h:25
SamplerContext
This is a special class object that holds a handle to the sampler state object given by the graphics ...
Definition: samplerContext.h:34
SamplerState
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
SamplerState::prepare_now
SamplerContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg) const
Creates a context for the sampler on the particular GSG, if it does not already exist.
Definition: samplerState.cxx:237
SavedContext
This is the base class for all GSG-specific context objects, such as TextureContext and GeomContext.
Definition: savedContext.h:26
ShaderBuffer
This is a generic buffer object that lives in graphics memory.
Definition: shaderBuffer.h:33
ShaderContext
The ShaderContext is meant to contain the compiled version of a shader string.
Definition: shaderContext.h:31
Shader
Definition: shader.h:49
Shader::prepare_now
ShaderContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the shader on the particular GSG, if it does not already exist.
Definition: shader.cxx:3711
Shader::is_prepared
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const
Returns true if the shader has already been prepared or enqueued for preparation on the indicated GSG...
Definition: shader.cxx:3668
TextureContext
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: textureContext.h:33
TextureContext::get_texture
Texture * get_texture() const
Returns the pointer to the associated Texture object.
Definition: textureContext.I:29
TextureContext::get_view
int get_view() const
Returns the specific view of a multiview texture this context represents.
Definition: textureContext.I:38
Texture
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
Texture::prepare_now
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
Definition: texture.cxx:1981
Texture::get_num_views
get_num_views
Returns the number of "views" in the texture.
Definition: texture.h:354
Texture::release
bool release(PreparedGraphicsObjects *prepared_objects)
Frees the texture context only on the indicated object, if it exists there.
Definition: texture.cxx:1573
Texture::is_prepared
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const
Returns true if the texture has already been prepared or enqueued for preparation on the indicated GS...
Definition: texture.cxx:1444
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
TypedWritableReferenceCount
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
Definition: typedWritableReferenceCount.h:31
VertexBufferContext
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: vertexBufferContext.h:33
VertexBufferContext::get_data
GeomVertexArrayData * get_data() const
Returns the pointer to the client-side array data object.
Definition: vertexBufferContext.I:28
plist< BufferCacheKey >
pmap< BufferCacheKey, BufferList >
pvector
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
config_gobj.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomPrimitive.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomVertexArrayData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geom.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indexBufferContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT
PT(PreparedGraphicsObjects::EnqueuedObject) PreparedGraphicsObjects
Like enqueue_texture, but returns an AsyncFuture that can be used to query the status of the texture'...
Definition: preparedGraphicsObjects.cxx:203
preparedGraphicsObjects.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
reMutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
samplerContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
shaderContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
shader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
textureContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
texture.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
throw_event.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
vertexBufferContext.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.