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