Line data Source code
1 :
2 : /* Copyright (c) 2007-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Cedric Stalder <cedric.stalder@gmail.com>
4 : * Daniel Nachbaur <danielnachbaur@gmail.com>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "objectManager.h"
21 :
22 : #include "accum.h"
23 : #include "bitmapFont.h"
24 : #include "frameBufferObject.h"
25 : #include "pixelBufferObject.h"
26 : #include "texture.h"
27 :
28 : #include <eq/gl.h>
29 : #include <lunchbox/hash.h>
30 : #include <lunchbox/os.h>
31 : #include <lunchbox/referenced.h>
32 : #include <pression/uploader.h>
33 : #include <string.h>
34 :
35 : //#define EQ_OM_TRACE_ALLOCATIONS
36 :
37 : namespace eq
38 : {
39 : namespace util
40 : {
41 : namespace
42 : {
43 : struct Object
44 : {
45 : unsigned id;
46 : unsigned num;
47 : };
48 :
49 : typedef std::unordered_map<const void*, Object> ObjectHash;
50 : typedef std::unordered_map<const void*, Texture*> TextureHash;
51 : typedef std::unordered_map<const void*, FrameBufferObject*> FBOHash;
52 : typedef std::unordered_map<const void*, PixelBufferObject*> PBOHash;
53 : typedef std::unordered_map<const void*, util::BitmapFont*> FontHash;
54 : typedef std::unordered_map<const void*, Accum*> AccumHash;
55 : typedef std::unordered_map<const void*, pression::Uploader*> UploaderHash;
56 : #ifdef EQ_OM_TRACE_ALLOCATIONS
57 : typedef std::unordered_map<const void*, std::string> UploaderAllocs;
58 : #endif
59 : }
60 :
61 : namespace detail
62 : {
63 : class ObjectManager : public lunchbox::Referenced
64 : {
65 : public:
66 8 : explicit ObjectManager(const GLEWContext* gl)
67 8 : {
68 8 : if (gl)
69 2 : memcpy(&glewContext, gl, sizeof(GLEWContext));
70 : else
71 6 : lunchbox::setZero(&glewContext, sizeof(GLEWContext));
72 7 : }
73 :
74 16 : virtual ~ObjectManager()
75 16 : {
76 : // Do not delete GL objects, we may no longer have a GL context.
77 8 : if (!lists.empty())
78 0 : LBWARN << lists.size()
79 0 : << " lists allocated in ObjectManager destructor"
80 0 : << std::endl;
81 8 : LBASSERT(lists.empty());
82 8 : lists.clear();
83 :
84 8 : if (!textures.empty())
85 0 : LBWARN << textures.size()
86 0 : << " textures allocated in ObjectManager destructor"
87 0 : << std::endl;
88 8 : LBASSERT(textures.empty());
89 8 : textures.clear();
90 :
91 8 : if (!buffers.empty())
92 0 : LBWARN << buffers.size()
93 0 : << " buffers allocated in ObjectManager destructor"
94 0 : << std::endl;
95 8 : LBASSERT(buffers.empty());
96 8 : buffers.clear();
97 :
98 8 : if (!programs.empty())
99 0 : LBWARN << programs.size()
100 0 : << " programs allocated in ObjectManager destructor"
101 0 : << std::endl;
102 8 : LBASSERT(programs.empty());
103 8 : programs.clear();
104 :
105 8 : if (!shaders.empty())
106 0 : LBWARN << shaders.size()
107 0 : << " shaders allocated in ObjectManager destructor"
108 0 : << std::endl;
109 8 : LBASSERT(shaders.empty());
110 8 : shaders.clear();
111 :
112 8 : if (!eqTextures.empty())
113 0 : LBWARN << eqTextures.size()
114 0 : << " eq::Texture allocated in ObjectManager destructor"
115 0 : << std::endl;
116 8 : LBASSERT(eqTextures.empty());
117 8 : eqTextures.clear();
118 :
119 8 : if (!eqFonts.empty())
120 0 : LBWARN << eqFonts.size()
121 0 : << " eq::BitmapFont allocated in ObjectManager destructor"
122 0 : << std::endl;
123 8 : LBASSERT(eqFonts.empty());
124 8 : eqFonts.clear();
125 :
126 8 : if (!eqFrameBufferObjects.empty())
127 0 : LBWARN << eqFrameBufferObjects.size()
128 : << " eq::FrameBufferObject's allocated in ObjectManager "
129 0 : << "destructor" << std::endl;
130 8 : LBASSERT(eqFrameBufferObjects.empty());
131 8 : eqFrameBufferObjects.clear();
132 :
133 8 : if (!eqUploaders.empty())
134 0 : LBWARN << eqUploaders.size()
135 0 : << " uploader allocated in ObjectManager destructor"
136 0 : << std::endl;
137 :
138 : #ifdef EQ_OM_TRACE_ALLOCATIONS
139 : LBASSERTINFO(eqUploaders.empty(), eqUploaderAllocs.begin()->second);
140 : #else
141 8 : LBASSERTINFO(eqUploaders.empty(), (void*)eqUploaders.begin()->second);
142 : #endif
143 8 : eqUploaders.clear();
144 16 : }
145 :
146 : GLEWContext glewContext;
147 : ObjectHash lists;
148 : ObjectHash vertexArrays;
149 : ObjectHash textures;
150 : ObjectHash buffers;
151 : ObjectHash programs;
152 : ObjectHash shaders;
153 : ObjectHash uploaderDatas;
154 : AccumHash accums;
155 : TextureHash eqTextures;
156 : FBOHash eqFrameBufferObjects;
157 : PBOHash eqPixelBufferObjects;
158 : FontHash eqFonts;
159 : UploaderHash eqUploaders;
160 : #ifdef EQ_OM_TRACE_ALLOCATIONS
161 : UploaderAllocs eqUploaderAllocs;
162 : #endif
163 : };
164 : }
165 :
166 4 : ObjectManager::ObjectManager(const GLEWContext* const glewContext)
167 4 : : _impl(new detail::ObjectManager(glewContext))
168 : {
169 4 : }
170 :
171 0 : ObjectManager::ObjectManager(const ObjectManager& shared)
172 0 : : _impl(shared._impl)
173 : {
174 0 : LBASSERT(_impl);
175 0 : LBASSERT(glewGetContext());
176 0 : }
177 :
178 4 : ObjectManager::~ObjectManager()
179 : {
180 4 : }
181 :
182 2 : ObjectManager& ObjectManager::operator=(const ObjectManager& rhs)
183 : {
184 2 : if (this != &rhs)
185 2 : _impl = rhs._impl;
186 2 : LBASSERT(glewGetContext());
187 2 : return *this;
188 : }
189 :
190 4 : void ObjectManager::clear()
191 : {
192 4 : _impl = new detail::ObjectManager(0);
193 4 : }
194 :
195 8 : bool ObjectManager::isShared() const
196 : {
197 8 : return _impl->getRefCount() > 1;
198 : }
199 :
200 4 : const GLEWContext* ObjectManager::glewGetContext() const
201 : {
202 4 : return &_impl->glewContext;
203 : }
204 :
205 4 : void ObjectManager::deleteAll()
206 : {
207 12 : for (ObjectHash::const_iterator i = _impl->lists.begin();
208 8 : i != _impl->lists.end(); ++i)
209 : {
210 0 : const Object& object = i->second;
211 0 : LBVERB << "Delete list " << object.id << std::endl;
212 0 : EQ_GL_CALL(glDeleteLists(object.id, object.num));
213 : }
214 4 : _impl->lists.clear();
215 :
216 12 : for (ObjectHash::const_iterator i = _impl->textures.begin();
217 8 : i != _impl->textures.end(); ++i)
218 : {
219 0 : const Object& object = i->second;
220 0 : LBVERB << "Delete texture " << object.id << std::endl;
221 0 : EQ_GL_CALL(glDeleteTextures(1, &object.id));
222 : }
223 4 : _impl->textures.clear();
224 :
225 12 : for (ObjectHash::const_iterator i = _impl->buffers.begin();
226 8 : i != _impl->buffers.end(); ++i)
227 : {
228 0 : const Object& object = i->second;
229 0 : LBVERB << "Delete buffer " << object.id << std::endl;
230 0 : EQ_GL_CALL(glDeleteBuffers(1, &object.id));
231 : }
232 4 : _impl->buffers.clear();
233 :
234 12 : for (ObjectHash::const_iterator i = _impl->programs.begin();
235 8 : i != _impl->programs.end(); ++i)
236 : {
237 0 : const Object& object = i->second;
238 0 : LBVERB << "Delete program " << object.id << std::endl;
239 0 : EQ_GL_CALL(glDeleteProgram(object.id));
240 : }
241 4 : _impl->programs.clear();
242 :
243 12 : for (ObjectHash::const_iterator i = _impl->shaders.begin();
244 8 : i != _impl->shaders.end(); ++i)
245 : {
246 0 : const Object& object = i->second;
247 0 : LBVERB << "Delete shader " << object.id << std::endl;
248 0 : EQ_GL_CALL(glDeleteShader(object.id));
249 : }
250 4 : _impl->shaders.clear();
251 :
252 12 : for (TextureHash::const_iterator i = _impl->eqTextures.begin();
253 8 : i != _impl->eqTextures.end(); ++i)
254 : {
255 0 : Texture* texture = i->second;
256 0 : LBVERB << "Delete eq::Texture " << i->first << " @" << (void*)texture
257 0 : << std::endl;
258 0 : texture->flush();
259 0 : delete texture;
260 : }
261 4 : _impl->eqTextures.clear();
262 :
263 12 : for (FontHash::const_iterator i = _impl->eqFonts.begin();
264 8 : i != _impl->eqFonts.end(); ++i)
265 : {
266 0 : util::BitmapFont* font = i->second;
267 0 : LBVERB << "Delete eq::Font " << i->first << " @" << (void*)font
268 0 : << std::endl;
269 0 : font->exit();
270 0 : delete font;
271 : }
272 4 : _impl->eqFonts.clear();
273 :
274 12 : for (FBOHash::const_iterator i = _impl->eqFrameBufferObjects.begin();
275 8 : i != _impl->eqFrameBufferObjects.end(); ++i)
276 : {
277 0 : FrameBufferObject* frameBufferObject = i->second;
278 0 : LBVERB << "Delete eq::FrameBufferObject " << i->first << " @"
279 0 : << (void*)frameBufferObject << std::endl;
280 0 : frameBufferObject->exit();
281 0 : delete frameBufferObject;
282 : }
283 4 : _impl->eqFrameBufferObjects.clear();
284 :
285 12 : for (UploaderHash::const_iterator i = _impl->eqUploaders.begin();
286 8 : i != _impl->eqUploaders.end(); ++i)
287 : {
288 0 : pression::Uploader* uploader = i->second;
289 0 : LBVERB << "Delete uploader " << i->first << " @" << (void*)uploader
290 0 : << std::endl;
291 0 : uploader->clear();
292 0 : delete uploader;
293 : }
294 4 : _impl->eqUploaders.clear();
295 4 : }
296 :
297 : // display list functions
298 :
299 0 : GLuint ObjectManager::getList(const void* key) const
300 : {
301 0 : ObjectHash::const_iterator i = _impl->lists.find(key);
302 0 : if (i == _impl->lists.end())
303 0 : return INVALID;
304 :
305 0 : const Object& object = i->second;
306 0 : return object.id;
307 : }
308 :
309 0 : GLuint ObjectManager::newList(const void* key, const GLsizei num)
310 : {
311 0 : if (_impl->lists.find(key) != _impl->lists.end())
312 : {
313 0 : LBWARN << "Requested new list for existing key" << std::endl;
314 0 : return INVALID;
315 : }
316 :
317 0 : const GLuint id = glGenLists(num);
318 0 : if (!id)
319 : {
320 0 : LBWARN << "glGenLists failed: " << glGetError() << std::endl;
321 0 : return INVALID;
322 : }
323 :
324 0 : Object& object = _impl->lists[key];
325 0 : object.id = id;
326 0 : object.num = num;
327 :
328 0 : return id;
329 : }
330 :
331 0 : GLuint ObjectManager::obtainList(const void* key, const GLsizei num)
332 : {
333 0 : const GLuint id = getList(key);
334 0 : if (id != INVALID)
335 0 : return id;
336 0 : return newList(key, num);
337 : }
338 :
339 0 : void ObjectManager::deleteList(const void* key)
340 : {
341 0 : ObjectHash::iterator i = _impl->lists.find(key);
342 0 : if (i == _impl->lists.end())
343 0 : return;
344 :
345 0 : const Object& object = i->second;
346 0 : EQ_GL_CALL(glDeleteLists(object.id, object.num));
347 0 : _impl->lists.erase(i);
348 : }
349 :
350 : // vertex array functions
351 :
352 0 : GLuint ObjectManager::getVertexArray(const void* key) const
353 : {
354 0 : ObjectHash::const_iterator i = _impl->vertexArrays.find(key);
355 0 : if (i == _impl->vertexArrays.end())
356 0 : return INVALID;
357 :
358 0 : const Object& object = i->second;
359 0 : return object.id;
360 : }
361 :
362 0 : GLuint ObjectManager::newVertexArray(const void* key)
363 : {
364 0 : if (_impl->vertexArrays.find(key) != _impl->vertexArrays.end())
365 : {
366 0 : LBWARN << "Requested new vertex array for existing key" << std::endl;
367 0 : return INVALID;
368 : }
369 :
370 0 : GLuint id = INVALID;
371 0 : EQ_GL_CALL(glGenVertexArrays(1, &id));
372 0 : if (!id)
373 : {
374 0 : LBWARN << "glGenVertexArrays failed: " << glGetError() << std::endl;
375 0 : return INVALID;
376 : }
377 :
378 0 : Object& object = _impl->vertexArrays[key];
379 0 : object.id = id;
380 0 : return id;
381 : }
382 :
383 0 : GLuint ObjectManager::obtainVertexArray(const void* key)
384 : {
385 0 : const GLuint id = getVertexArray(key);
386 0 : if (id != INVALID)
387 0 : return id;
388 0 : return newVertexArray(key);
389 : }
390 :
391 0 : void ObjectManager::deleteVertexArray(const void* key)
392 : {
393 0 : ObjectHash::iterator i = _impl->vertexArrays.find(key);
394 0 : if (i == _impl->vertexArrays.end())
395 0 : return;
396 :
397 0 : const Object& object = i->second;
398 0 : EQ_GL_CALL(glDeleteVertexArrays(1, &object.id));
399 0 : _impl->vertexArrays.erase(i);
400 : }
401 :
402 : // texture object functions
403 :
404 0 : GLuint ObjectManager::getTexture(const void* key) const
405 : {
406 0 : ObjectHash::const_iterator i = _impl->textures.find(key);
407 0 : if (i == _impl->textures.end())
408 0 : return INVALID;
409 :
410 0 : const Object& object = i->second;
411 0 : return object.id;
412 : }
413 :
414 0 : GLuint ObjectManager::newTexture(const void* key)
415 : {
416 0 : if (_impl->textures.find(key) != _impl->textures.end())
417 : {
418 0 : LBWARN << "Requested new texture for existing key" << std::endl;
419 0 : return INVALID;
420 : }
421 :
422 0 : GLuint id = INVALID;
423 0 : glGenTextures(1, &id);
424 0 : if (id == INVALID)
425 : {
426 0 : LBWARN << "glGenTextures failed: " << glGetError() << std::endl;
427 0 : return INVALID;
428 : }
429 :
430 0 : Object& object = _impl->textures[key];
431 0 : object.id = id;
432 0 : return id;
433 : }
434 :
435 0 : GLuint ObjectManager::obtainTexture(const void* key)
436 : {
437 0 : const GLuint id = getTexture(key);
438 0 : if (id != INVALID)
439 0 : return id;
440 0 : return newTexture(key);
441 : }
442 :
443 0 : void ObjectManager::deleteTexture(const void* key)
444 : {
445 0 : ObjectHash::iterator i = _impl->textures.find(key);
446 0 : if (i == _impl->textures.end())
447 0 : return;
448 :
449 0 : const Object& object = i->second;
450 0 : EQ_GL_CALL(glDeleteTextures(1, &object.id));
451 0 : _impl->textures.erase(i);
452 : }
453 :
454 : // buffer object functions
455 :
456 0 : bool ObjectManager::supportsBuffers() const
457 : {
458 0 : return (GLEW_VERSION_1_5);
459 : }
460 :
461 0 : GLuint ObjectManager::getBuffer(const void* key) const
462 : {
463 0 : ObjectHash::const_iterator i = _impl->buffers.find(key);
464 0 : if (i == _impl->buffers.end())
465 0 : return INVALID;
466 :
467 0 : const Object& object = i->second;
468 0 : return object.id;
469 : }
470 :
471 0 : GLuint ObjectManager::newBuffer(const void* key)
472 : {
473 0 : if (!GLEW_VERSION_1_5)
474 : {
475 0 : LBWARN << "glGenBuffers not available" << std::endl;
476 0 : return INVALID;
477 : }
478 :
479 0 : if (_impl->buffers.find(key) != _impl->buffers.end())
480 : {
481 0 : LBWARN << "Requested new buffer for existing key " << key << std::endl;
482 0 : return INVALID;
483 : }
484 :
485 0 : GLuint id = INVALID;
486 0 : glGenBuffers(1, &id);
487 0 : if (id == INVALID)
488 : {
489 0 : LBWARN << "glGenBuffers failed: " << glGetError() << std::endl;
490 0 : return INVALID;
491 : }
492 :
493 0 : Object& object = _impl->buffers[key];
494 0 : object.id = id;
495 0 : return id;
496 : }
497 :
498 0 : GLuint ObjectManager::obtainBuffer(const void* key)
499 : {
500 0 : const GLuint id = getBuffer(key);
501 0 : if (id != INVALID)
502 0 : return id;
503 0 : return newBuffer(key);
504 : }
505 :
506 0 : void ObjectManager::deleteBuffer(const void* key)
507 : {
508 0 : ObjectHash::iterator i = _impl->buffers.find(key);
509 0 : if (i == _impl->buffers.end())
510 0 : return;
511 :
512 0 : const Object& object = i->second;
513 0 : EQ_GL_CALL(glDeleteBuffers(1, &object.id));
514 0 : _impl->buffers.erase(i);
515 : }
516 :
517 : // program object functions
518 :
519 0 : bool ObjectManager::supportsPrograms() const
520 : {
521 0 : return (GLEW_VERSION_2_0);
522 : }
523 :
524 0 : GLuint ObjectManager::getProgram(const void* key) const
525 : {
526 0 : ObjectHash::const_iterator i = _impl->programs.find(key);
527 0 : if (i == _impl->programs.end())
528 0 : return INVALID;
529 :
530 0 : const Object& object = i->second;
531 0 : return object.id;
532 : }
533 :
534 0 : GLuint ObjectManager::newProgram(const void* key)
535 : {
536 0 : if (!GLEW_VERSION_2_0)
537 : {
538 0 : LBWARN << "glCreateProgram not available" << std::endl;
539 0 : return INVALID;
540 : }
541 :
542 0 : if (_impl->programs.find(key) != _impl->programs.end())
543 : {
544 0 : LBWARN << "Requested new program for existing key" << std::endl;
545 0 : return INVALID;
546 : }
547 :
548 0 : const GLuint id = glCreateProgram();
549 0 : if (!id)
550 : {
551 0 : LBWARN << "glCreateProgram failed: " << glGetError() << std::endl;
552 0 : return INVALID;
553 : }
554 :
555 0 : Object& object = _impl->programs[key];
556 0 : object.id = id;
557 0 : return id;
558 : }
559 :
560 0 : GLuint ObjectManager::obtainProgram(const void* key)
561 : {
562 0 : const GLuint id = getProgram(key);
563 0 : if (id != INVALID)
564 0 : return id;
565 0 : return newProgram(key);
566 : }
567 :
568 0 : void ObjectManager::deleteProgram(const void* key)
569 : {
570 0 : ObjectHash::iterator i = _impl->programs.find(key);
571 0 : if (i == _impl->programs.end())
572 0 : return;
573 :
574 0 : const Object& object = i->second;
575 0 : EQ_GL_CALL(glDeleteProgram(object.id));
576 0 : _impl->programs.erase(i);
577 : }
578 :
579 : // shader object functions
580 :
581 0 : bool ObjectManager::supportsShaders() const
582 : {
583 0 : return (GLEW_VERSION_2_0);
584 : }
585 :
586 0 : GLuint ObjectManager::getShader(const void* key) const
587 : {
588 0 : ObjectHash::const_iterator i = _impl->shaders.find(key);
589 0 : if (i == _impl->shaders.end())
590 0 : return INVALID;
591 :
592 0 : const Object& object = i->second;
593 0 : return object.id;
594 : }
595 :
596 0 : GLuint ObjectManager::newShader(const void* key, const GLenum type)
597 : {
598 0 : if (!GLEW_VERSION_2_0)
599 : {
600 0 : LBWARN << "glCreateShader not available" << std::endl;
601 0 : return INVALID;
602 : }
603 :
604 0 : if (_impl->shaders.find(key) != _impl->shaders.end())
605 : {
606 0 : LBWARN << "Requested new shader for existing key" << std::endl;
607 0 : return INVALID;
608 : }
609 :
610 0 : const GLuint id = glCreateShader(type);
611 0 : if (!id)
612 : {
613 0 : LBWARN << "glCreateShader failed: " << glGetError() << std::endl;
614 0 : return INVALID;
615 : }
616 :
617 0 : Object& object = _impl->shaders[key];
618 0 : object.id = id;
619 0 : return id;
620 : }
621 :
622 0 : GLuint ObjectManager::obtainShader(const void* key, const GLenum type)
623 : {
624 0 : const GLuint id = getShader(key);
625 0 : if (id != INVALID)
626 0 : return id;
627 0 : return newShader(key, type);
628 : }
629 :
630 0 : void ObjectManager::deleteShader(const void* key)
631 : {
632 0 : ObjectHash::iterator i = _impl->shaders.find(key);
633 0 : if (i == _impl->shaders.end())
634 0 : return;
635 :
636 0 : const Object& object = i->second;
637 0 : EQ_GL_CALL(glDeleteShader(object.id));
638 0 : _impl->shaders.erase(i);
639 : }
640 :
641 0 : Accum* ObjectManager::getEqAccum(const void* key) const
642 : {
643 0 : AccumHash::const_iterator i = _impl->accums.find(key);
644 0 : if (i == _impl->accums.end())
645 0 : return 0;
646 :
647 0 : return i->second;
648 : }
649 :
650 0 : Accum* ObjectManager::newEqAccum(const void* key)
651 : {
652 0 : if (_impl->accums.find(key) != _impl->accums.end())
653 : {
654 0 : LBWARN << "Requested new Accumulation for existing key" << std::endl;
655 0 : return 0;
656 : }
657 :
658 0 : Accum* accum = new Accum(&_impl->glewContext);
659 0 : _impl->accums[key] = accum;
660 0 : return accum;
661 : }
662 :
663 0 : Accum* ObjectManager::obtainEqAccum(const void* key)
664 : {
665 0 : Accum* accum = getEqAccum(key);
666 0 : if (accum)
667 0 : return accum;
668 0 : return newEqAccum(key);
669 : }
670 :
671 0 : void ObjectManager::deleteEqAccum(const void* key)
672 : {
673 0 : AccumHash::iterator i = _impl->accums.find(key);
674 0 : if (i == _impl->accums.end())
675 0 : return;
676 :
677 0 : Accum* accum = i->second;
678 0 : _impl->accums.erase(i);
679 :
680 0 : accum->exit();
681 0 : delete accum;
682 : }
683 :
684 : // eq::CompressorData object functions
685 1 : pression::Uploader* ObjectManager::getEqUploader(const void* key) const
686 : {
687 1 : UploaderHash::const_iterator i = _impl->eqUploaders.find(key);
688 1 : if (i == _impl->eqUploaders.end())
689 1 : return 0;
690 :
691 0 : return i->second;
692 : }
693 :
694 1 : pression::Uploader* ObjectManager::newEqUploader(const void* key)
695 : {
696 1 : if (_impl->eqUploaders.find(key) != _impl->eqUploaders.end())
697 : {
698 0 : LBWARN << "Requested new compressor for existing key" << std::endl;
699 0 : return 0;
700 : }
701 :
702 1 : pression::Uploader* compressor = new pression::Uploader;
703 1 : _impl->eqUploaders[key] = compressor;
704 : #ifdef EQ_OM_TRACE_ALLOCATIONS
705 : std::ostringstream out;
706 : out << lunchbox::backtrace;
707 : _impl->eqUploaderAllocs[key] = out.str();
708 : #endif
709 :
710 1 : return compressor;
711 : }
712 :
713 1 : pression::Uploader* ObjectManager::obtainEqUploader(const void* key)
714 : {
715 1 : pression::Uploader* compressor = getEqUploader(key);
716 1 : if (compressor)
717 0 : return compressor;
718 1 : return newEqUploader(key);
719 : }
720 :
721 8 : void ObjectManager::deleteEqUploader(const void* key)
722 : {
723 8 : UploaderHash::iterator i = _impl->eqUploaders.find(key);
724 8 : if (i == _impl->eqUploaders.end())
725 7 : return;
726 :
727 1 : pression::Uploader* uploader = i->second;
728 1 : _impl->eqUploaders.erase(i);
729 : #ifdef EQ_OM_TRACE_ALLOCATIONS
730 : _impl->eqUploaderAllocs.erase(key);
731 : #endif
732 1 : uploader->clear();
733 1 : delete uploader;
734 : }
735 :
736 : // eq::Texture object functions
737 0 : bool ObjectManager::supportsEqTexture() const
738 : {
739 0 : return (GLEW_ARB_texture_rectangle);
740 : }
741 :
742 0 : Texture* ObjectManager::getEqTexture(const void* key) const
743 : {
744 0 : TextureHash::const_iterator i = _impl->eqTextures.find(key);
745 0 : if (i == _impl->eqTextures.end())
746 0 : return 0;
747 :
748 0 : return i->second;
749 : }
750 :
751 0 : Texture* ObjectManager::newEqTexture(const void* key, const GLenum target)
752 : {
753 0 : if (_impl->eqTextures.find(key) != _impl->eqTextures.end())
754 : {
755 0 : LBWARN << "Requested new eqTexture for existing key" << std::endl;
756 0 : return 0;
757 : }
758 :
759 0 : Texture* texture = new Texture(target, &_impl->glewContext);
760 0 : _impl->eqTextures[key] = texture;
761 0 : return texture;
762 : }
763 :
764 0 : Texture* ObjectManager::obtainEqTexture(const void* key, const GLenum target)
765 : {
766 0 : Texture* texture = getEqTexture(key);
767 0 : if (texture)
768 0 : return texture;
769 0 : return newEqTexture(key, target);
770 : }
771 :
772 8 : void ObjectManager::deleteEqTexture(const void* key)
773 : {
774 8 : TextureHash::iterator i = _impl->eqTextures.find(key);
775 8 : if (i == _impl->eqTextures.end())
776 8 : return;
777 :
778 0 : Texture* texture = i->second;
779 0 : _impl->eqTextures.erase(i);
780 :
781 0 : texture->flush();
782 0 : delete texture;
783 : }
784 :
785 : // eq::util::BitmapFont object functions
786 0 : util::BitmapFont* ObjectManager::getEqBitmapFont(const void* key) const
787 : {
788 0 : FontHash::const_iterator i = _impl->eqFonts.find(key);
789 0 : if (i == _impl->eqFonts.end())
790 0 : return 0;
791 :
792 0 : return i->second;
793 : }
794 :
795 0 : util::BitmapFont* ObjectManager::newEqBitmapFont(const void* key)
796 : {
797 0 : if (_impl->eqFonts.find(key) != _impl->eqFonts.end())
798 : {
799 0 : LBWARN << "Requested new eqFont for existing key" << std::endl;
800 0 : return 0;
801 : }
802 :
803 0 : util::BitmapFont* font = new util::BitmapFont(*this, key);
804 0 : _impl->eqFonts[key] = font;
805 0 : return font;
806 : }
807 :
808 0 : util::BitmapFont* ObjectManager::obtainEqBitmapFont(const void* key)
809 : {
810 0 : util::BitmapFont* font = getEqBitmapFont(key);
811 0 : if (font)
812 0 : return font;
813 0 : return newEqBitmapFont(key);
814 : }
815 :
816 8 : void ObjectManager::deleteEqBitmapFont(const void* key)
817 : {
818 8 : FontHash::iterator i = _impl->eqFonts.find(key);
819 8 : if (i == _impl->eqFonts.end())
820 8 : return;
821 :
822 0 : util::BitmapFont* font = i->second;
823 0 : _impl->eqFonts.erase(i);
824 :
825 0 : font->exit();
826 0 : delete font;
827 : }
828 :
829 : // eq::FrameBufferObject object functions
830 0 : bool ObjectManager::supportsEqFrameBufferObject() const
831 : {
832 0 : return (GLEW_EXT_framebuffer_object);
833 : }
834 :
835 0 : FrameBufferObject* ObjectManager::getEqFrameBufferObject(const void* key) const
836 : {
837 0 : FBOHash::const_iterator i = _impl->eqFrameBufferObjects.find(key);
838 0 : if (i == _impl->eqFrameBufferObjects.end())
839 0 : return 0;
840 :
841 0 : return i->second;
842 : }
843 :
844 0 : FrameBufferObject* ObjectManager::newEqFrameBufferObject(const void* key)
845 : {
846 0 : if (_impl->eqFrameBufferObjects.find(key) !=
847 0 : _impl->eqFrameBufferObjects.end())
848 : {
849 0 : LBWARN << "Requested new eqFrameBufferObject for existing key"
850 0 : << std::endl;
851 0 : return 0;
852 : }
853 :
854 : FrameBufferObject* frameBufferObject =
855 0 : new FrameBufferObject(&_impl->glewContext);
856 0 : _impl->eqFrameBufferObjects[key] = frameBufferObject;
857 0 : return frameBufferObject;
858 : }
859 :
860 0 : FrameBufferObject* ObjectManager::obtainEqFrameBufferObject(const void* key)
861 : {
862 0 : FrameBufferObject* frameBufferObject = getEqFrameBufferObject(key);
863 0 : if (frameBufferObject)
864 0 : return frameBufferObject;
865 0 : return newEqFrameBufferObject(key);
866 : }
867 :
868 0 : void ObjectManager::deleteEqFrameBufferObject(const void* key)
869 : {
870 0 : FBOHash::iterator i = _impl->eqFrameBufferObjects.find(key);
871 0 : if (i == _impl->eqFrameBufferObjects.end())
872 0 : return;
873 :
874 0 : FrameBufferObject* frameBufferObject = i->second;
875 0 : _impl->eqFrameBufferObjects.erase(i);
876 :
877 0 : frameBufferObject->exit();
878 0 : delete frameBufferObject;
879 : }
880 :
881 : // eq::PixelBufferObject object functions
882 0 : bool ObjectManager::supportsEqPixelBufferObject() const
883 : {
884 0 : return (GLEW_ARB_pixel_buffer_object);
885 : }
886 :
887 0 : PixelBufferObject* ObjectManager::getEqPixelBufferObject(const void* key) const
888 : {
889 0 : PBOHash::const_iterator i = _impl->eqPixelBufferObjects.find(key);
890 0 : if (i == _impl->eqPixelBufferObjects.end())
891 0 : return 0;
892 :
893 0 : return i->second;
894 : }
895 :
896 0 : PixelBufferObject* ObjectManager::newEqPixelBufferObject(const void* key)
897 : {
898 0 : if (_impl->eqPixelBufferObjects.find(key) !=
899 0 : _impl->eqPixelBufferObjects.end())
900 : {
901 0 : LBWARN << "Requested new eqPixelBufferObject for existing key"
902 0 : << std::endl;
903 0 : return 0;
904 : }
905 :
906 : PixelBufferObject* pixelBufferObject =
907 0 : new PixelBufferObject(&_impl->glewContext);
908 0 : _impl->eqPixelBufferObjects[key] = pixelBufferObject;
909 0 : return pixelBufferObject;
910 : }
911 :
912 0 : PixelBufferObject* ObjectManager::obtainEqPixelBufferObject(const void* key)
913 : {
914 0 : PixelBufferObject* pixelBufferObject = getEqPixelBufferObject(key);
915 0 : if (pixelBufferObject)
916 0 : return pixelBufferObject;
917 0 : return newEqPixelBufferObject(key);
918 : }
919 :
920 0 : void ObjectManager::deleteEqPixelBufferObject(const void* key)
921 : {
922 0 : PBOHash::iterator i = _impl->eqPixelBufferObjects.find(key);
923 0 : if (i == _impl->eqPixelBufferObjects.end())
924 0 : return;
925 :
926 0 : PixelBufferObject* pixelBufferObject = i->second;
927 0 : _impl->eqPixelBufferObjects.erase(i);
928 :
929 0 : pixelBufferObject->destroy();
930 0 : delete pixelBufferObject;
931 : }
932 : }
933 30 : }
|