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