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