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