0024271: Provide Boolean operations for NCollection_Map
[occt.git] / src / OpenGl / OpenGl_Context.cxx
... / ...
CommitLineData
1// Created on: 2012-01-26
2// Created by: Kirill GAVRILOV
3// Copyright (c) 2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
20#if defined(_WIN32)
21 #include <windows.h>
22#endif
23
24#include <OpenGl_Context.hxx>
25
26#include <OpenGl_ArbVBO.hxx>
27#include <OpenGl_ArbTBO.hxx>
28#include <OpenGl_ArbIns.hxx>
29#include <OpenGl_ArbDbg.hxx>
30#include <OpenGl_ExtFBO.hxx>
31#include <OpenGl_ExtGS.hxx>
32#include <OpenGl_GlCore20.hxx>
33
34#include <Message_Messenger.hxx>
35#include <NCollection_Vector.hxx>
36
37#include <Standard_ProgramError.hxx>
38
39#if defined(_WIN32)
40 //
41#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
42 #include <dlfcn.h>
43#else
44 #include <GL/glx.h> // glXGetProcAddress()
45#endif
46
47// GL_NVX_gpu_memory_info
48#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
49 enum
50 {
51 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
52 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
53 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
54 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
55 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
56 };
57#endif
58
59IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
60IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
61
62//! Make record shorter to retrieve function pointer using variable with same name
63#define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
64
65namespace
66{
67 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
68 static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
69};
70
71// =======================================================================
72// function : OpenGl_Context
73// purpose :
74// =======================================================================
75OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
76: core12 (NULL),
77 core13 (NULL),
78 core14 (NULL),
79 core15 (NULL),
80 core20 (NULL),
81 caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
82 arbNPTW(Standard_False),
83 arbVBO (NULL),
84 arbTBO (NULL),
85 arbIns (NULL),
86 arbDbg (NULL),
87 extFBO (NULL),
88 extGS (NULL),
89 extBgra(Standard_False),
90 extAnis(Standard_False),
91 extPDS(Standard_False),
92 atiMem (Standard_False),
93 nvxMem (Standard_False),
94 mySharedResources (new OpenGl_ResourcesMap()),
95 myDelayed (new OpenGl_DelayReleaseMap()),
96 myReleaseQueue (new OpenGl_ResourcesQueue()),
97 myClippingState (),
98 myGlLibHandle (NULL),
99 myGlCore20 (NULL),
100 myAnisoMax (1),
101 myMaxTexDim (1024),
102 myMaxClipPlanes (6),
103 myGlVerMajor (0),
104 myGlVerMinor (0),
105 myIsFeedback (Standard_False),
106 myIsInitialized (Standard_False)
107{
108#if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
109 // Vendors can not extend functionality on this system
110 // and developers are limited to OpenGL support provided by Mac OS X SDK.
111 // We retrieve function pointers from system library
112 // to generalize extensions support on all platforms.
113 // In this way we also reach binary compatibility benefit between OS releases
114 // if some newest functionality is optionally used.
115 // Notice that GL version / extension availability checks are required
116 // because function pointers may be available but not functionality itself
117 // (depends on renderer).
118 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
119#endif
120}
121
122// =======================================================================
123// function : ~OpenGl_Context
124// purpose :
125// =======================================================================
126OpenGl_Context::~OpenGl_Context()
127{
128 // release clean up queue
129 ReleaseDelayed();
130
131 // release shared resources if any
132 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
133 {
134 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
135 anIter.More(); anIter.Next())
136 {
137 anIter.Value()->Release (this);
138 }
139 }
140 mySharedResources.Nullify();
141 myDelayed.Nullify();
142
143 if (arbDbg != NULL
144 && caps->contextDebug)
145 {
146 // reset callback
147 void* aPtr = NULL;
148 glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM_ARB, &aPtr);
149 if (aPtr == this)
150 {
151 arbDbg->glDebugMessageCallbackARB (NULL, NULL);
152 }
153 }
154
155 delete myGlCore20;
156 delete arbVBO;
157 delete arbTBO;
158 delete arbIns;
159 delete arbDbg;
160 delete extFBO;
161 delete extGS;
162}
163
164// =======================================================================
165// function : MaxDegreeOfAnisotropy
166// purpose :
167// =======================================================================
168Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
169{
170 return myAnisoMax;
171}
172
173// =======================================================================
174// function : MaxTextureSize
175// purpose :
176// =======================================================================
177Standard_Integer OpenGl_Context::MaxTextureSize() const
178{
179 return myMaxTexDim;
180}
181
182// =======================================================================
183// function : MaxClipPlanes
184// purpose :
185// =======================================================================
186Standard_Integer OpenGl_Context::MaxClipPlanes() const
187{
188 return myMaxClipPlanes;
189}
190
191// =======================================================================
192// function : Share
193// purpose :
194// =======================================================================
195void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
196{
197 if (!theShareCtx.IsNull())
198 {
199 mySharedResources = theShareCtx->mySharedResources;
200 myDelayed = theShareCtx->myDelayed;
201 myReleaseQueue = theShareCtx->myReleaseQueue;
202 }
203}
204
205#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
206
207// =======================================================================
208// function : IsCurrent
209// purpose :
210// =======================================================================
211Standard_Boolean OpenGl_Context::IsCurrent() const
212{
213#if defined(_WIN32)
214 if (myWindowDC == NULL || myGContext == NULL)
215 {
216 return Standard_False;
217 }
218 return (( (HDC )myWindowDC == wglGetCurrentDC())
219 && ((HGLRC )myGContext == wglGetCurrentContext()));
220#else
221 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
222 {
223 return Standard_False;
224 }
225
226 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
227 && ((GLXContext )myGContext == glXGetCurrentContext())
228 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
229#endif
230}
231
232// =======================================================================
233// function : MakeCurrent
234// purpose :
235// =======================================================================
236Standard_Boolean OpenGl_Context::MakeCurrent()
237{
238#if defined(_WIN32)
239 if (myWindowDC == NULL || myGContext == NULL)
240 {
241 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
242 return Standard_False;
243 }
244
245 // technically it should be safe to activate already bound GL context
246 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
247 if (IsCurrent())
248 {
249 return Standard_True;
250 }
251 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
252 {
253 // notice that glGetError() couldn't be used here!
254 wchar_t* aMsgBuff = NULL;
255 DWORD anErrorCode = GetLastError();
256 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
257 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
258 TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
259 if (aMsgBuff != NULL)
260 {
261 aMsg += (Standard_ExtString )aMsgBuff;
262 LocalFree (aMsgBuff);
263 }
264 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
265 return Standard_False;
266 }
267#else
268 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
269 {
270 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
271 return Standard_False;
272 }
273
274 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
275 {
276 // if there is no current context it might be impossible to use glGetError() correctly
277 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
278 "glXMakeCurrent() has failed!");
279 return Standard_False;
280 }
281#endif
282 return Standard_True;
283}
284
285// =======================================================================
286// function : SwapBuffers
287// purpose :
288// =======================================================================
289void OpenGl_Context::SwapBuffers()
290{
291#if defined(_WIN32)
292 if ((HDC )myWindowDC != NULL)
293 {
294 ::SwapBuffers ((HDC )myWindowDC);
295 glFlush();
296 }
297#else
298 if ((Display* )myDisplay != NULL)
299 {
300 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
301 }
302#endif
303}
304
305#endif // __APPLE__
306
307// =======================================================================
308// function : findProc
309// purpose :
310// =======================================================================
311void* OpenGl_Context::findProc (const char* theFuncName)
312{
313#if defined(_WIN32)
314 return wglGetProcAddress (theFuncName);
315#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
316 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
317#else
318 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
319#endif
320}
321
322// =======================================================================
323// function : CheckExtension
324// purpose :
325// =======================================================================
326Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
327{
328 if (theExtName == NULL)
329 {
330 std::cerr << "CheckExtension called with NULL string!\n";
331 return Standard_False;
332 }
333
334 // available since OpenGL 3.0
335 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
336 /**if (IsGlGreaterEqual (3, 0))
337 {
338 GLint anExtNb = 0;
339 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
340 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
341 {
342 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
343 if (anExtension[anExtNameLen] == '\0' &&
344 strncmp (anExtension, theExtName, anExtNameLen) == 0)
345 {
346 return Standard_True;
347 }
348 }
349 return Standard_False;
350 }*/
351
352 // use old way with huge string for all extensions
353 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
354 if (anExtString == NULL)
355 {
356 Messanger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
357 return Standard_False;
358 }
359 return CheckExtension (anExtString, theExtName);
360}
361
362// =======================================================================
363// function : CheckExtension
364// purpose :
365// =======================================================================
366Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
367 const char* theExtName)
368{
369 if (theExtString == NULL)
370 {
371 return Standard_False;
372 }
373
374 // Search for theExtName in the extensions string.
375 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
376 char* aPtrIter = (char* )theExtString;
377 const char* aPtrEnd = aPtrIter + strlen (theExtString);
378 const size_t anExtNameLen = strlen (theExtName);
379 while (aPtrIter < aPtrEnd)
380 {
381 const size_t n = strcspn (aPtrIter, " ");
382 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
383 {
384 return Standard_True;
385 }
386 aPtrIter += (n + 1);
387 }
388 return Standard_False;
389}
390
391#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
392
393// =======================================================================
394// function : Init
395// purpose :
396// =======================================================================
397Standard_Boolean OpenGl_Context::Init()
398{
399 if (myIsInitialized)
400 {
401 return Standard_True;
402 }
403
404#if defined(_WIN32)
405 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
406 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
407#else
408 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
409 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
410 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
411#endif
412 if (myGContext == NULL)
413 {
414 return Standard_False;
415 }
416
417 init();
418 myIsInitialized = Standard_True;
419 return Standard_True;
420}
421
422#endif // __APPLE__
423
424// =======================================================================
425// function : Init
426// purpose :
427// =======================================================================
428#if defined(_WIN32)
429Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
430 const Aspect_Handle theWindowDC,
431 const Aspect_RenderingContext theGContext)
432#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
433Standard_Boolean OpenGl_Context::Init (const void* theGContext)
434#else
435Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
436 const Aspect_Display theDisplay,
437 const Aspect_RenderingContext theGContext)
438#endif
439{
440 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
441#if defined(_WIN32)
442 myWindow = theWindow;
443 myGContext = theGContext;
444 myWindowDC = theWindowDC;
445#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
446 myGContext = (void* )theGContext;
447#else
448 myWindow = theWindow;
449 myGContext = theGContext;
450 myDisplay = theDisplay;
451#endif
452 if (myGContext == NULL || !MakeCurrent())
453 {
454 return Standard_False;
455 }
456
457 init();
458 myIsInitialized = Standard_True;
459 return Standard_True;
460}
461
462// =======================================================================
463// function : ResetErrors
464// purpose :
465// =======================================================================
466void OpenGl_Context::ResetErrors()
467{
468 while (glGetError() != GL_NO_ERROR)
469 {
470 //
471 }
472}
473
474// =======================================================================
475// function : readGlVersion
476// purpose :
477// =======================================================================
478void OpenGl_Context::readGlVersion()
479{
480 // reset values
481 myGlVerMajor = 0;
482 myGlVerMinor = 0;
483
484 // available since OpenGL 3.0
485 GLint aMajor = 0, aMinor = 0;
486 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
487 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
488 // glGetError() sometimes does not report an error here even if
489 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
490 // This happens on some rendereres like e.g. Cygwin MESA.
491 // Thus checking additionally if GL has put anything to
492 // the output variables.
493 if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
494 {
495 myGlVerMajor = aMajor;
496 myGlVerMinor = aMinor;
497 return;
498 }
499 ResetErrors();
500
501 // Read version string.
502 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
503 // Following trash (after space) is vendor-specific.
504 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
505 // and should be considered as vendor-specific too.
506 const char* aVerStr = (const char* )glGetString (GL_VERSION);
507 if (aVerStr == NULL || *aVerStr == '\0')
508 {
509 // invalid GL context
510 return;
511 }
512
513 // parse string for major number
514 char aMajorStr[32];
515 char aMinorStr[32];
516 size_t aMajIter = 0;
517 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
518 {
519 ++aMajIter;
520 }
521 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
522 {
523 return;
524 }
525 memcpy (aMajorStr, aVerStr, aMajIter);
526 aMajorStr[aMajIter] = '\0';
527
528 // parse string for minor number
529 aVerStr += aMajIter + 1;
530 size_t aMinIter = 0;
531 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
532 {
533 ++aMinIter;
534 }
535 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
536 {
537 return;
538 }
539 memcpy (aMinorStr, aVerStr, aMinIter);
540 aMinorStr[aMinIter] = '\0';
541
542 // read numbers
543 myGlVerMajor = atoi (aMajorStr);
544 myGlVerMinor = atoi (aMinorStr);
545
546 if (myGlVerMajor <= 0)
547 {
548 myGlVerMajor = 0;
549 myGlVerMinor = 0;
550 }
551}
552
553static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
554static Standard_CString THE_DBGMSG_SOURCES[] =
555{
556 ".OpenGL", // GL_DEBUG_SOURCE_API_ARB
557 ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
558 ".GLSL", // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
559 ".3rdParty", // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
560 "", // GL_DEBUG_SOURCE_APPLICATION_ARB
561 ".Other" // GL_DEBUG_SOURCE_OTHER_ARB
562};
563
564static Standard_CString THE_DBGMSG_TYPES[] =
565{
566 "Error", // GL_DEBUG_TYPE_ERROR_ARB
567 "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
568 "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
569 "Portability", // GL_DEBUG_TYPE_PORTABILITY_ARB
570 "Performance", // GL_DEBUG_TYPE_PERFORMANCE_ARB
571 "Other" // GL_DEBUG_TYPE_OTHER_ARB
572};
573
574static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH_ARB
575static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
576static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW_ARB
577
578//! Callback for GL_ARB_debug_output extension
579static void APIENTRY debugCallbackWrap(unsigned int theSource,
580 unsigned int theType,
581 unsigned int theId,
582 unsigned int theSeverity,
583 int /*theLength*/,
584 const char* theMessage,
585 void* theUserParam)
586{
587 OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
588 aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
589}
590
591// =======================================================================
592// function : PushMessage
593// purpose :
594// =======================================================================
595void OpenGl_Context::PushMessage (const unsigned int theSource,
596 const unsigned int theType,
597 const unsigned int theId,
598 const unsigned int theSeverity,
599 const TCollection_ExtendedString& theMessage)
600{
601 //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
602 Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
603 && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
604 ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
605 : THE_DBGMSG_UNKNOWN;
606 Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
607 && theType <= GL_DEBUG_TYPE_OTHER_ARB)
608 ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
609 : THE_DBGMSG_UNKNOWN;
610 Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
611 ? THE_DBGMSG_SEV_HIGH
612 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
613 ? THE_DBGMSG_SEV_MEDIUM
614 : THE_DBGMSG_SEV_LOW);
615 Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
616 ? Message_Alarm
617 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
618 ? Message_Warning
619 : Message_Info);
620
621 TCollection_ExtendedString aMsg;
622 aMsg += "TKOpenGl"; aMsg += aSrc;
623 aMsg += " | Type: "; aMsg += aType;
624 aMsg += " | ID: "; aMsg += (Standard_Integer )theId;
625 aMsg += " | Severity: "; aMsg += aSev;
626 aMsg += " | Message:\n ";
627 aMsg += theMessage;
628
629 Messanger()->Send (aMsg, aGrav);
630}
631
632// =======================================================================
633// function : init
634// purpose :
635// =======================================================================
636void OpenGl_Context::init()
637{
638 // read version
639 readGlVersion();
640
641 arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
642 extBgra = CheckExtension ("GL_EXT_bgra");
643 extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
644 extPDS = CheckExtension ("GL_EXT_packed_depth_stencil");
645 atiMem = CheckExtension ("GL_ATI_meminfo");
646 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
647
648 // get number of maximum clipping planes
649 glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
650 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
651 if (extAnis)
652 {
653 glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
654 }
655
656 myClippingState.Init (myMaxClipPlanes);
657
658 // initialize debug context extension
659 if (CheckExtension ("GL_ARB_debug_output"))
660 {
661 arbDbg = new OpenGl_ArbDbg();
662 memset (arbDbg, 0, sizeof(OpenGl_ArbDbg)); // nullify whole structure
663 if (!FindProcShort (arbDbg, glDebugMessageControlARB)
664 || !FindProcShort (arbDbg, glDebugMessageInsertARB)
665 || !FindProcShort (arbDbg, glDebugMessageCallbackARB)
666 || !FindProcShort (arbDbg, glGetDebugMessageLogARB))
667 {
668 delete arbDbg;
669 arbDbg = NULL;
670 }
671 if (arbDbg != NULL
672 && caps->contextDebug)
673 {
674 // setup default callback
675 arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
676 #ifdef DEB
677 glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
678 #endif
679 }
680 }
681
682 // initialize VBO extension (ARB)
683 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
684 {
685 arbVBO = new OpenGl_ArbVBO();
686 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
687 if (!FindProcShort (arbVBO, glGenBuffersARB)
688 || !FindProcShort (arbVBO, glBindBufferARB)
689 || !FindProcShort (arbVBO, glBufferDataARB)
690 || !FindProcShort (arbVBO, glDeleteBuffersARB))
691 {
692 delete arbVBO;
693 arbVBO = NULL;
694 }
695 }
696
697 // initialize TBO extension (ARB)
698 if (CheckExtension ("GL_ARB_texture_buffer_object"))
699 {
700 arbTBO = new OpenGl_ArbTBO();
701 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
702 if (!FindProcShort (arbTBO, glTexBufferARB))
703 {
704 delete arbTBO;
705 arbTBO = NULL;
706 }
707 }
708
709 // initialize hardware instancing extension (ARB)
710 if (CheckExtension ("GL_ARB_draw_instanced"))
711 {
712 arbIns = new OpenGl_ArbIns();
713 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
714 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
715 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
716 {
717 delete arbIns;
718 arbIns = NULL;
719 }
720 }
721
722 // initialize FBO extension (EXT)
723 if (CheckExtension ("GL_EXT_framebuffer_object"))
724 {
725 extFBO = new OpenGl_ExtFBO();
726 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
727 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
728 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
729 || !FindProcShort (extFBO, glBindFramebufferEXT)
730 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
731 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
732 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
733 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
734 || !FindProcShort (extFBO, glBindRenderbufferEXT)
735 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
736 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT)
737 || !FindProcShort (extFBO, glGenerateMipmapEXT))
738 {
739 delete extFBO;
740 extFBO = NULL;
741 }
742 }
743
744 // initialize GS extension (EXT)
745 if (CheckExtension ("GL_EXT_geometry_shader4"))
746 {
747 extGS = new OpenGl_ExtGS();
748 memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
749 if (!FindProcShort (extGS, glProgramParameteriEXT))
750 {
751 delete extGS;
752 extGS = NULL;
753 }
754 }
755
756 myGlCore20 = new OpenGl_GlCore20();
757 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
758
759 // Check if OpenGL 1.2 core functionality is actually present
760 Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
761 && FindProcShort (myGlCore20, glBlendColor)
762 && FindProcShort (myGlCore20, glBlendEquation)
763 && FindProcShort (myGlCore20, glDrawRangeElements)
764 && FindProcShort (myGlCore20, glTexImage3D)
765 && FindProcShort (myGlCore20, glTexSubImage3D)
766 && FindProcShort (myGlCore20, glCopyTexSubImage3D);
767
768 // Check if OpenGL 1.3 core functionality is actually present
769 Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
770 && FindProcShort (myGlCore20, glActiveTexture)
771 && FindProcShort (myGlCore20, glSampleCoverage)
772 && FindProcShort (myGlCore20, glCompressedTexImage3D)
773 && FindProcShort (myGlCore20, glCompressedTexImage2D)
774 && FindProcShort (myGlCore20, glCompressedTexImage1D)
775 && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
776 && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
777 && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
778 && FindProcShort (myGlCore20, glGetCompressedTexImage)
779 // deprecated
780 && FindProcShort (myGlCore20, glClientActiveTexture)
781 && FindProcShort (myGlCore20, glMultiTexCoord1d)
782 && FindProcShort (myGlCore20, glMultiTexCoord1dv)
783 && FindProcShort (myGlCore20, glMultiTexCoord1f)
784 && FindProcShort (myGlCore20, glMultiTexCoord1fv)
785 && FindProcShort (myGlCore20, glMultiTexCoord1i)
786 && FindProcShort (myGlCore20, glMultiTexCoord1iv)
787 && FindProcShort (myGlCore20, glMultiTexCoord1s)
788 && FindProcShort (myGlCore20, glMultiTexCoord1sv)
789 && FindProcShort (myGlCore20, glMultiTexCoord2d)
790 && FindProcShort (myGlCore20, glMultiTexCoord2dv)
791 && FindProcShort (myGlCore20, glMultiTexCoord2f)
792 && FindProcShort (myGlCore20, glMultiTexCoord2fv)
793 && FindProcShort (myGlCore20, glMultiTexCoord2i)
794 && FindProcShort (myGlCore20, glMultiTexCoord2iv)
795 && FindProcShort (myGlCore20, glMultiTexCoord2s)
796 && FindProcShort (myGlCore20, glMultiTexCoord2sv)
797 && FindProcShort (myGlCore20, glMultiTexCoord3d)
798 && FindProcShort (myGlCore20, glMultiTexCoord3dv)
799 && FindProcShort (myGlCore20, glMultiTexCoord3f)
800 && FindProcShort (myGlCore20, glMultiTexCoord3fv)
801 && FindProcShort (myGlCore20, glMultiTexCoord3i)
802 && FindProcShort (myGlCore20, glMultiTexCoord3iv)
803 && FindProcShort (myGlCore20, glMultiTexCoord3s)
804 && FindProcShort (myGlCore20, glMultiTexCoord3sv)
805 && FindProcShort (myGlCore20, glMultiTexCoord4d)
806 && FindProcShort (myGlCore20, glMultiTexCoord4dv)
807 && FindProcShort (myGlCore20, glMultiTexCoord4f)
808 && FindProcShort (myGlCore20, glMultiTexCoord4fv)
809 && FindProcShort (myGlCore20, glMultiTexCoord4i)
810 && FindProcShort (myGlCore20, glMultiTexCoord4iv)
811 && FindProcShort (myGlCore20, glMultiTexCoord4s)
812 && FindProcShort (myGlCore20, glMultiTexCoord4sv)
813 && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
814 && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
815 && FindProcShort (myGlCore20, glMultTransposeMatrixf)
816 && FindProcShort (myGlCore20, glMultTransposeMatrixd);
817
818 // Check if OpenGL 1.4 core functionality is actually present
819 Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
820 && FindProcShort (myGlCore20, glBlendFuncSeparate)
821 && FindProcShort (myGlCore20, glMultiDrawArrays)
822 && FindProcShort (myGlCore20, glMultiDrawElements)
823 && FindProcShort (myGlCore20, glPointParameterf)
824 && FindProcShort (myGlCore20, glPointParameterfv)
825 && FindProcShort (myGlCore20, glPointParameteri)
826 && FindProcShort (myGlCore20, glPointParameteriv);
827
828 // Check if OpenGL 1.5 core functionality is actually present
829 Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
830 && FindProcShort (myGlCore20, glGenQueries)
831 && FindProcShort (myGlCore20, glDeleteQueries)
832 && FindProcShort (myGlCore20, glIsQuery)
833 && FindProcShort (myGlCore20, glBeginQuery)
834 && FindProcShort (myGlCore20, glEndQuery)
835 && FindProcShort (myGlCore20, glGetQueryiv)
836 && FindProcShort (myGlCore20, glGetQueryObjectiv)
837 && FindProcShort (myGlCore20, glGetQueryObjectuiv)
838 && FindProcShort (myGlCore20, glBindBuffer)
839 && FindProcShort (myGlCore20, glDeleteBuffers)
840 && FindProcShort (myGlCore20, glGenBuffers)
841 && FindProcShort (myGlCore20, glIsBuffer)
842 && FindProcShort (myGlCore20, glBufferData)
843 && FindProcShort (myGlCore20, glBufferSubData)
844 && FindProcShort (myGlCore20, glGetBufferSubData)
845 && FindProcShort (myGlCore20, glMapBuffer)
846 && FindProcShort (myGlCore20, glUnmapBuffer)
847 && FindProcShort (myGlCore20, glGetBufferParameteriv)
848 && FindProcShort (myGlCore20, glGetBufferPointerv);
849
850 // Check if OpenGL 2.0 core functionality is actually present
851 Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
852 && FindProcShort (myGlCore20, glBlendEquationSeparate)
853 && FindProcShort (myGlCore20, glDrawBuffers)
854 && FindProcShort (myGlCore20, glStencilOpSeparate)
855 && FindProcShort (myGlCore20, glStencilFuncSeparate)
856 && FindProcShort (myGlCore20, glStencilMaskSeparate)
857 && FindProcShort (myGlCore20, glAttachShader)
858 && FindProcShort (myGlCore20, glBindAttribLocation)
859 && FindProcShort (myGlCore20, glCompileShader)
860 && FindProcShort (myGlCore20, glCreateProgram)
861 && FindProcShort (myGlCore20, glCreateShader)
862 && FindProcShort (myGlCore20, glDeleteProgram)
863 && FindProcShort (myGlCore20, glDeleteShader)
864 && FindProcShort (myGlCore20, glDetachShader)
865 && FindProcShort (myGlCore20, glDisableVertexAttribArray)
866 && FindProcShort (myGlCore20, glEnableVertexAttribArray)
867 && FindProcShort (myGlCore20, glGetActiveAttrib)
868 && FindProcShort (myGlCore20, glGetActiveUniform)
869 && FindProcShort (myGlCore20, glGetAttachedShaders)
870 && FindProcShort (myGlCore20, glGetAttribLocation)
871 && FindProcShort (myGlCore20, glGetProgramiv)
872 && FindProcShort (myGlCore20, glGetProgramInfoLog)
873 && FindProcShort (myGlCore20, glGetShaderiv)
874 && FindProcShort (myGlCore20, glGetShaderInfoLog)
875 && FindProcShort (myGlCore20, glGetShaderSource)
876 && FindProcShort (myGlCore20, glGetUniformLocation)
877 && FindProcShort (myGlCore20, glGetUniformfv)
878 && FindProcShort (myGlCore20, glGetUniformiv)
879 && FindProcShort (myGlCore20, glGetVertexAttribdv)
880 && FindProcShort (myGlCore20, glGetVertexAttribfv)
881 && FindProcShort (myGlCore20, glGetVertexAttribiv)
882 && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
883 && FindProcShort (myGlCore20, glIsProgram)
884 && FindProcShort (myGlCore20, glIsShader)
885 && FindProcShort (myGlCore20, glLinkProgram)
886 && FindProcShort (myGlCore20, glShaderSource)
887 && FindProcShort (myGlCore20, glUseProgram)
888 && FindProcShort (myGlCore20, glUniform1f)
889 && FindProcShort (myGlCore20, glUniform2f)
890 && FindProcShort (myGlCore20, glUniform3f)
891 && FindProcShort (myGlCore20, glUniform4f)
892 && FindProcShort (myGlCore20, glUniform1i)
893 && FindProcShort (myGlCore20, glUniform2i)
894 && FindProcShort (myGlCore20, glUniform3i)
895 && FindProcShort (myGlCore20, glUniform4i)
896 && FindProcShort (myGlCore20, glUniform1fv)
897 && FindProcShort (myGlCore20, glUniform2fv)
898 && FindProcShort (myGlCore20, glUniform3fv)
899 && FindProcShort (myGlCore20, glUniform4fv)
900 && FindProcShort (myGlCore20, glUniform1iv)
901 && FindProcShort (myGlCore20, glUniform2iv)
902 && FindProcShort (myGlCore20, glUniform3iv)
903 && FindProcShort (myGlCore20, glUniform4iv)
904 && FindProcShort (myGlCore20, glUniformMatrix2fv)
905 && FindProcShort (myGlCore20, glUniformMatrix3fv)
906 && FindProcShort (myGlCore20, glUniformMatrix4fv)
907 && FindProcShort (myGlCore20, glValidateProgram)
908 && FindProcShort (myGlCore20, glVertexAttrib1d)
909 && FindProcShort (myGlCore20, glVertexAttrib1dv)
910 && FindProcShort (myGlCore20, glVertexAttrib1f)
911 && FindProcShort (myGlCore20, glVertexAttrib1fv)
912 && FindProcShort (myGlCore20, glVertexAttrib1s)
913 && FindProcShort (myGlCore20, glVertexAttrib1sv)
914 && FindProcShort (myGlCore20, glVertexAttrib2d)
915 && FindProcShort (myGlCore20, glVertexAttrib2dv)
916 && FindProcShort (myGlCore20, glVertexAttrib2f)
917 && FindProcShort (myGlCore20, glVertexAttrib2fv)
918 && FindProcShort (myGlCore20, glVertexAttrib2s)
919 && FindProcShort (myGlCore20, glVertexAttrib2sv)
920 && FindProcShort (myGlCore20, glVertexAttrib3d)
921 && FindProcShort (myGlCore20, glVertexAttrib3dv)
922 && FindProcShort (myGlCore20, glVertexAttrib3f)
923 && FindProcShort (myGlCore20, glVertexAttrib3fv)
924 && FindProcShort (myGlCore20, glVertexAttrib3s)
925 && FindProcShort (myGlCore20, glVertexAttrib3sv)
926 && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
927 && FindProcShort (myGlCore20, glVertexAttrib4Niv)
928 && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
929 && FindProcShort (myGlCore20, glVertexAttrib4Nub)
930 && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
931 && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
932 && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
933 && FindProcShort (myGlCore20, glVertexAttrib4bv)
934 && FindProcShort (myGlCore20, glVertexAttrib4d)
935 && FindProcShort (myGlCore20, glVertexAttrib4dv)
936 && FindProcShort (myGlCore20, glVertexAttrib4f)
937 && FindProcShort (myGlCore20, glVertexAttrib4fv)
938 && FindProcShort (myGlCore20, glVertexAttrib4iv)
939 && FindProcShort (myGlCore20, glVertexAttrib4s)
940 && FindProcShort (myGlCore20, glVertexAttrib4sv)
941 && FindProcShort (myGlCore20, glVertexAttrib4ubv)
942 && FindProcShort (myGlCore20, glVertexAttrib4uiv)
943 && FindProcShort (myGlCore20, glVertexAttrib4usv)
944 && FindProcShort (myGlCore20, glVertexAttribPointer);
945
946 if (!hasGlCore12)
947 {
948 myGlVerMajor = 1;
949 myGlVerMinor = 1;
950 return;
951 }
952 else
953 {
954 core12 = myGlCore20;
955 }
956 if (!hasGlCore13)
957 {
958 myGlVerMajor = 1;
959 myGlVerMinor = 2;
960 return;
961 }
962 else
963 {
964 core13 = myGlCore20;
965 }
966 if(!hasGlCore14)
967 {
968 myGlVerMajor = 1;
969 myGlVerMinor = 3;
970 return;
971 }
972 else
973 {
974 core14 = myGlCore20;
975 }
976 if(!hasGlCore15)
977 {
978 myGlVerMajor = 1;
979 myGlVerMinor = 4;
980 return;
981 }
982 else
983 {
984 core15 = myGlCore20;
985 }
986 if(!hasGlCore20)
987 {
988 myGlVerMajor = 1;
989 myGlVerMinor = 5;
990 }
991 else
992 {
993 core20 = myGlCore20;
994 }
995}
996// =======================================================================
997// function : IsFeedback
998// purpose :
999// =======================================================================
1000Standard_Boolean OpenGl_Context::IsFeedback() const
1001{
1002 return myIsFeedback;
1003}
1004
1005// =======================================================================
1006// function : SetFeedback
1007// purpose :
1008// =======================================================================
1009void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
1010{
1011 myIsFeedback = theFeedbackOn;
1012}
1013
1014// =======================================================================
1015// function : MemoryInfo
1016// purpose :
1017// =======================================================================
1018Standard_Size OpenGl_Context::AvailableMemory() const
1019{
1020 if (atiMem)
1021 {
1022 // this is actually information for VBO pool
1023 // however because pools are mostly shared
1024 // it can be used for total GPU memory estimations
1025 GLint aMemInfo[4];
1026 aMemInfo[0] = 0;
1027 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1028 // returned value is in KiB, however this maybe changed in future
1029 return Standard_Size(aMemInfo[0]) * 1024;
1030 }
1031 else if (nvxMem)
1032 {
1033 // current available dedicated video memory (in KiB), currently unused GPU memory
1034 GLint aMemInfo = 0;
1035 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1036 return Standard_Size(aMemInfo) * 1024;
1037 }
1038 return 0;
1039}
1040
1041// =======================================================================
1042// function : MemoryInfo
1043// purpose :
1044// =======================================================================
1045TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1046{
1047 TCollection_AsciiString anInfo;
1048 if (atiMem)
1049 {
1050 GLint aValues[4];
1051 memset (aValues, 0, sizeof(aValues));
1052 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1053
1054 // total memory free in the pool
1055 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
1056
1057 // largest available free block in the pool
1058 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1059 if (aValues[2] != aValues[0])
1060 {
1061 // total auxiliary memory free
1062 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
1063 }
1064 }
1065 else if (nvxMem)
1066 {
1067 //current available dedicated video memory (in KiB), currently unused GPU memory
1068 GLint aValue = 0;
1069 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1070 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
1071
1072 // dedicated video memory, total size (in KiB) of the GPU memory
1073 GLint aDedicated = 0;
1074 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
1075 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
1076
1077 // total available memory, total size (in KiB) of the memory available for allocations
1078 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1079 if (aValue != aDedicated)
1080 {
1081 // different only for special configurations
1082 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
1083 }
1084 }
1085 return anInfo;
1086}
1087
1088
1089// =======================================================================
1090// function : GetResource
1091// purpose :
1092// =======================================================================
1093const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
1094{
1095 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
1096}
1097
1098// =======================================================================
1099// function : ShareResource
1100// purpose :
1101// =======================================================================
1102Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
1103 const Handle(OpenGl_Resource)& theResource)
1104{
1105 if (theKey.IsEmpty() || theResource.IsNull())
1106 {
1107 return Standard_False;
1108 }
1109 return mySharedResources->Bind (theKey, theResource);
1110}
1111
1112// =======================================================================
1113// function : ReleaseResource
1114// purpose :
1115// =======================================================================
1116void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
1117 const Standard_Boolean theToDelay)
1118{
1119 if (!mySharedResources->IsBound (theKey))
1120 {
1121 return;
1122 }
1123 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
1124 if (aRes->GetRefCount() > 1)
1125 {
1126 return;
1127 }
1128
1129 if (theToDelay)
1130 {
1131 myDelayed->Bind (theKey, 1);
1132 }
1133 else
1134 {
1135 aRes->Release (this);
1136 mySharedResources->UnBind (theKey);
1137 }
1138}
1139
1140// =======================================================================
1141// function : DelayedRelease
1142// purpose :
1143// =======================================================================
1144void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
1145{
1146 myReleaseQueue->Push (theResource);
1147 theResource.Nullify();
1148}
1149
1150// =======================================================================
1151// function : ReleaseDelayed
1152// purpose :
1153// =======================================================================
1154void OpenGl_Context::ReleaseDelayed()
1155{
1156 // release queued elements
1157 while (!myReleaseQueue->IsEmpty())
1158 {
1159 myReleaseQueue->Front()->Release (this);
1160 myReleaseQueue->Pop();
1161 }
1162
1163 // release delayed shared resoruces
1164 NCollection_Vector<TCollection_AsciiString> aDeadList;
1165 for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
1166 anIter.More(); anIter.Next())
1167 {
1168 if (++anIter.ChangeValue() <= 2)
1169 {
1170 continue; // postpone release one more frame to ensure noone use it periodically
1171 }
1172
1173 const TCollection_AsciiString& aKey = anIter.Key();
1174 if (!mySharedResources->IsBound (aKey))
1175 {
1176 // mixed unshared strategy delayed/undelayed was used!
1177 aDeadList.Append (aKey);
1178 continue;
1179 }
1180
1181 Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
1182 if (aRes->GetRefCount() > 1)
1183 {
1184 // should be only 1 instance in mySharedResources
1185 // if not - resource was reused again
1186 aDeadList.Append (aKey);
1187 continue;
1188 }
1189
1190 // release resource if no one requiested it more than 2 redraw calls
1191 aRes->Release (this);
1192 mySharedResources->UnBind (aKey);
1193 aDeadList.Append (aKey);
1194 }
1195
1196 for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
1197 {
1198 myDelayed->UnBind (aDeadList.Value (anIter));
1199 }
1200}