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