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