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