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